From 694149b2592b17e0a172caa3a9ad223ba9669aa3 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Wed, 1 Feb 2023 17:58:02 +0530 Subject: [PATCH 01/17] Cacao moved to utills --- .../Common/SIWEMessageFormatter.swift | 92 ++----------------- .../Wallet/WalletRespondService.swift | 2 +- Sources/Auth/Types/AuthPayload.swift | 16 ++++ Sources/Auth/Types/Cacao/Cacao.swift | 10 -- Sources/Auth/Types/Cacao/CacaoHeader.swift | 5 - Sources/Auth/Types/Cacao/CacaoPayload.swift | 29 ------ .../AuthenticationService.swift | 12 +++ .../AuthenticationStorage.swift | 12 +++ .../Authentication/IdentityKeyService.swift | 38 ++++++++ Sources/WalletConnectUtils/Cacao/Cacao.swift | 16 ++++ .../Cacao/CacaoHeader.swift | 9 ++ .../Cacao/CacaoPayload.swift | 41 +++++++++ .../Cacao/CacaoSignature.swift | 6 +- .../DIDPKH}/DIDPKH.swift | 13 +-- .../SIWE/SIWECacaoFormatter.swift | 30 ++++++ .../WalletConnectUtils/SIWE/SIWEMessage.swift | 72 +++++++++++++++ .../AuthTests/AppRespondSubscriberTests.swift | 2 +- 17 files changed, 264 insertions(+), 141 deletions(-) delete mode 100644 Sources/Auth/Types/Cacao/Cacao.swift delete mode 100644 Sources/Auth/Types/Cacao/CacaoHeader.swift delete mode 100644 Sources/Auth/Types/Cacao/CacaoPayload.swift create mode 100644 Sources/Chat/ProtocolServices/Authentication/AuthenticationService.swift create mode 100644 Sources/Chat/ProtocolServices/Authentication/AuthenticationStorage.swift create mode 100644 Sources/Chat/ProtocolServices/Authentication/IdentityKeyService.swift create mode 100644 Sources/WalletConnectUtils/Cacao/Cacao.swift create mode 100644 Sources/WalletConnectUtils/Cacao/CacaoHeader.swift create mode 100644 Sources/WalletConnectUtils/Cacao/CacaoPayload.swift rename Sources/{Auth/Types => WalletConnectUtils}/Cacao/CacaoSignature.swift (76%) rename Sources/{Auth/Services/Signer => WalletConnectUtils/DIDPKH}/DIDPKH.swift (73%) create mode 100644 Sources/WalletConnectUtils/SIWE/SIWECacaoFormatter.swift create mode 100644 Sources/WalletConnectUtils/SIWE/SIWEMessage.swift diff --git a/Sources/Auth/Services/Common/SIWEMessageFormatter.swift b/Sources/Auth/Services/Common/SIWEMessageFormatter.swift index 5e8c82d57..0e4034d5f 100644 --- a/Sources/Auth/Services/Common/SIWEMessageFormatter.swift +++ b/Sources/Auth/Services/Common/SIWEMessageFormatter.swift @@ -14,96 +14,16 @@ public struct SIWEMessageFormatter: SIWEMessageFormatting { public init() { } public func formatMessage(from payload: AuthPayload, address: String) throws -> String { - guard let chain = Blockchain(payload.chainId) else { + guard + let blockchain = Blockchain(payload.chainId), + let account = Account(blockchain: blockchain, address: address) else { throw Errors.invalidChainID } - let message = SIWEMessage( - domain: payload.domain, - uri: payload.aud, - address: address, - version: payload.version, - nonce: payload.nonce, - chainId: chain.reference, - iat: payload.iat, - nbf: payload.nbf, - exp: payload.exp, - statement: payload.statement, - requestId: payload.requestId, - resources: payload.resources - ) - return message.formatted + let payload = payload.cacaoPayload(didpkh: DIDPKH(account: account)) + return try formatMessage(from: payload) } func formatMessage(from payload: CacaoPayload) throws -> String { - let address = try DIDPKH(iss: payload.iss).account.address - let iss = try DIDPKH(iss: payload.iss) - let message = SIWEMessage( - domain: payload.domain, - uri: payload.aud, - address: address, - version: payload.version, - nonce: payload.nonce, - chainId: iss.account.reference, - iat: payload.iat, - nbf: payload.nbf, - exp: payload.exp, - statement: payload.statement, - requestId: payload.requestId, - resources: payload.resources - ) - return message.formatted - } -} - -private struct SIWEMessage: Equatable { - let domain: String - let uri: String // aud - let address: String - let version: String - let nonce: String - let chainId: String - let iat: String - let nbf: String? - let exp: String? - let statement: String? - let requestId: String? - let resources: [String]? - - var formatted: String { - return """ - \(domain) wants you to sign in with your Ethereum account: - \(address) - \(statementLine) - URI: \(uri) - Version: \(version) - Chain ID: \(chainId) - Nonce: \(nonce) - Issued At: \(iat)\(expLine)\(nbfLine)\(requestIdLine)\(resourcesSection) - """ - } - - var expLine: String { - guard let exp = exp else { return "" } - return "\nExpiration Time: \(exp)" - } - - var statementLine: String { - guard let statement = statement else { return "" } - return "\n\(statement)\n" - } - - var nbfLine: String { - guard let nbf = nbf else { return "" } - return "\nNot Before: \(nbf)" - } - - var requestIdLine: String { - guard let requestId = requestId else { return "" } - return "\nRequest ID: \(requestId)" - } - - var resourcesSection: String { - guard let resources = resources else { return "" } - return resources.reduce("\nResources:") { $0 + "\n- \($1)" } + return try SIWECacaoFormatter().formatMessage(from: payload) } } diff --git a/Sources/Auth/Services/Wallet/WalletRespondService.swift b/Sources/Auth/Services/Wallet/WalletRespondService.swift index 595489aa3..8ea1946e9 100644 --- a/Sources/Auth/Services/Wallet/WalletRespondService.swift +++ b/Sources/Auth/Services/Wallet/WalletRespondService.swift @@ -31,7 +31,7 @@ actor WalletRespondService { let didpkh = DIDPKH(account: account) let header = CacaoHeader(t: "eip4361") - let payload = CacaoPayload(params: authRequestParams.payloadParams, didpkh: didpkh) + let payload = authRequestParams.payloadParams.cacaoPayload(didpkh: didpkh) let responseParams = AuthResponseParams(h: header, p: payload, s: signature) let response = RPCResponse(id: requestId, result: responseParams) diff --git a/Sources/Auth/Types/AuthPayload.swift b/Sources/Auth/Types/AuthPayload.swift index 621df1ea3..00d8b934b 100644 --- a/Sources/Auth/Types/AuthPayload.swift +++ b/Sources/Auth/Types/AuthPayload.swift @@ -28,4 +28,20 @@ public struct AuthPayload: Codable, Equatable { self.requestId = requestParams.requestId self.resources = requestParams.resources } + + func cacaoPayload(didpkh: DIDPKH) -> CacaoPayload { + return CacaoPayload( + iss: didpkh.iss, + domain: domain, + aud: aud, + version: version, + nonce: nonce, + iat: iat, + nbf: nbf, + exp: exp, + statement: statement, + requestId: requestId, + resources: resources + ) + } } diff --git a/Sources/Auth/Types/Cacao/Cacao.swift b/Sources/Auth/Types/Cacao/Cacao.swift deleted file mode 100644 index a82da2ab4..000000000 --- a/Sources/Auth/Types/Cacao/Cacao.swift +++ /dev/null @@ -1,10 +0,0 @@ -import Foundation - -/// CAIP-74 Cacao object -/// -/// specs at: https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-74.md -public struct Cacao: Codable, Equatable { - let h: CacaoHeader - let p: CacaoPayload - let s: CacaoSignature -} diff --git a/Sources/Auth/Types/Cacao/CacaoHeader.swift b/Sources/Auth/Types/Cacao/CacaoHeader.swift deleted file mode 100644 index 1461f3ae4..000000000 --- a/Sources/Auth/Types/Cacao/CacaoHeader.swift +++ /dev/null @@ -1,5 +0,0 @@ -import Foundation - -struct CacaoHeader: Codable, Equatable { - let t: String -} diff --git a/Sources/Auth/Types/Cacao/CacaoPayload.swift b/Sources/Auth/Types/Cacao/CacaoPayload.swift deleted file mode 100644 index 41f66e736..000000000 --- a/Sources/Auth/Types/Cacao/CacaoPayload.swift +++ /dev/null @@ -1,29 +0,0 @@ -import Foundation - -struct CacaoPayload: Codable, Equatable { - let iss: String - let domain: String - let aud: String - let version: String - let nonce: String - let iat: String - let nbf: String? - let exp: String? - let statement: String? - let requestId: String? - let resources: [String]? - - init(params: AuthPayload, didpkh: DIDPKH) { - self.iss = didpkh.iss - self.domain = params.domain - self.aud = params.aud - self.version = "1" - self.nonce = params.nonce - self.iat = params.iat - self.nbf = params.nbf - self.exp = params.exp - self.statement = params.statement - self.requestId = params.requestId - self.resources = params.resources - } -} diff --git a/Sources/Chat/ProtocolServices/Authentication/AuthenticationService.swift b/Sources/Chat/ProtocolServices/Authentication/AuthenticationService.swift new file mode 100644 index 000000000..b1dead4ed --- /dev/null +++ b/Sources/Chat/ProtocolServices/Authentication/AuthenticationService.swift @@ -0,0 +1,12 @@ +import Foundation + +final class AuthenticationService { + + private let accountService: AccountService + + init(accountService: AccountService) { + self.accountService = accountService + } + + +} diff --git a/Sources/Chat/ProtocolServices/Authentication/AuthenticationStorage.swift b/Sources/Chat/ProtocolServices/Authentication/AuthenticationStorage.swift new file mode 100644 index 000000000..f5430e7bf --- /dev/null +++ b/Sources/Chat/ProtocolServices/Authentication/AuthenticationStorage.swift @@ -0,0 +1,12 @@ +import Foundation + +typealias IdentityKey = SigningPrivateKey + +final class AuthenticationStorage { + + private let kms: KeychainServiceProtocol + + init(kms: KeychainServiceProtocol) { + self.kms = kms + } +} diff --git a/Sources/Chat/ProtocolServices/Authentication/IdentityKeyService.swift b/Sources/Chat/ProtocolServices/Authentication/IdentityKeyService.swift new file mode 100644 index 000000000..256eec8c6 --- /dev/null +++ b/Sources/Chat/ProtocolServices/Authentication/IdentityKeyService.swift @@ -0,0 +1,38 @@ +import Foundation + +enum IdentityKeyAPI: HTTPService { + + case register(cacao: String) // TODO: Cacao + case resolve(publicKey: String) + + var path: String { + return "/identity" + } + + var method: WalletConnectNetworking.HTTPMethod { + switch self { + case .register: + return .post + case .resolve: + return .get + } + } + + var body: Data? { + switch self { + case .register(let cacao): + return try? JSONEncoder().encode(cacao) + case .resolve: + return nil + } + } + + var queryParameters: [String : String]? { + switch self { + case .register: + return nil + case .resolve(let publicKey): + return ["publicKey": publicKey] + } + } +} diff --git a/Sources/WalletConnectUtils/Cacao/Cacao.swift b/Sources/WalletConnectUtils/Cacao/Cacao.swift new file mode 100644 index 000000000..5c938594b --- /dev/null +++ b/Sources/WalletConnectUtils/Cacao/Cacao.swift @@ -0,0 +1,16 @@ +import Foundation + +/// CAIP-74 Cacao object +/// +/// specs at: https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-74.md +public struct Cacao: Codable, Equatable { + public let h: CacaoHeader + public let p: CacaoPayload + public let s: CacaoSignature + + public init(h: CacaoHeader, p: CacaoPayload, s: CacaoSignature) { + self.h = h + self.p = p + self.s = s + } +} diff --git a/Sources/WalletConnectUtils/Cacao/CacaoHeader.swift b/Sources/WalletConnectUtils/Cacao/CacaoHeader.swift new file mode 100644 index 000000000..897c314d4 --- /dev/null +++ b/Sources/WalletConnectUtils/Cacao/CacaoHeader.swift @@ -0,0 +1,9 @@ +import Foundation + +public struct CacaoHeader: Codable, Equatable { + public let t: String + + public init(t: String) { + self.t = t + } +} diff --git a/Sources/WalletConnectUtils/Cacao/CacaoPayload.swift b/Sources/WalletConnectUtils/Cacao/CacaoPayload.swift new file mode 100644 index 000000000..3711f3ef0 --- /dev/null +++ b/Sources/WalletConnectUtils/Cacao/CacaoPayload.swift @@ -0,0 +1,41 @@ +import Foundation + +public struct CacaoPayload: Codable, Equatable { + public let iss: String + public let domain: String + public let aud: String + public let version: String + public let nonce: String + public let iat: String + public let nbf: String? + public let exp: String? + public let statement: String? + public let requestId: String? + public let resources: [String]? + + public init( + iss: String, + domain: String, + aud: String, + version: String, + nonce: String, + iat: String, + nbf: String?, + exp: String?, + statement: String?, + requestId: String?, + resources: [String]? + ) { + self.iss = iss + self.domain = domain + self.aud = aud + self.version = version + self.nonce = nonce + self.iat = iat + self.nbf = nbf + self.exp = exp + self.statement = statement + self.requestId = requestId + self.resources = resources + } +} diff --git a/Sources/Auth/Types/Cacao/CacaoSignature.swift b/Sources/WalletConnectUtils/Cacao/CacaoSignature.swift similarity index 76% rename from Sources/Auth/Types/Cacao/CacaoSignature.swift rename to Sources/WalletConnectUtils/Cacao/CacaoSignature.swift index 7137f9dea..d272f0279 100644 --- a/Sources/Auth/Types/Cacao/CacaoSignature.swift +++ b/Sources/WalletConnectUtils/Cacao/CacaoSignature.swift @@ -6,9 +6,9 @@ public enum CacaoSignatureType: String, Codable { } public struct CacaoSignature: Codable, Equatable { - let t: CacaoSignatureType - let s: String - let m: String? + public let t: CacaoSignatureType + public let s: String + public let m: String? public init(t: CacaoSignatureType, s: String, m: String? = nil) { self.t = t diff --git a/Sources/Auth/Services/Signer/DIDPKH.swift b/Sources/WalletConnectUtils/DIDPKH/DIDPKH.swift similarity index 73% rename from Sources/Auth/Services/Signer/DIDPKH.swift rename to Sources/WalletConnectUtils/DIDPKH/DIDPKH.swift index 1475a6530..a625b231a 100644 --- a/Sources/Auth/Services/Signer/DIDPKH.swift +++ b/Sources/WalletConnectUtils/DIDPKH/DIDPKH.swift @@ -1,17 +1,18 @@ import Foundation -struct DIDPKH { - static let didPrefix: String = "did:pkh" +public struct DIDPKH { + + private static let didPrefix: String = "did:pkh" enum Errors: Error { case invalidDIDPKH case invalidAccount } - let account: Account - let iss: String + public let account: Account + public let iss: String - init(iss: String) throws { + public init(iss: String) throws { guard iss.starts(with: DIDPKH.didPrefix) else { throw Errors.invalidDIDPKH } @@ -25,7 +26,7 @@ struct DIDPKH { self.account = account } - init(account: Account) { + public init(account: Account) { self.iss = "\(DIDPKH.didPrefix):\(account.absoluteString)" self.account = account } diff --git a/Sources/WalletConnectUtils/SIWE/SIWECacaoFormatter.swift b/Sources/WalletConnectUtils/SIWE/SIWECacaoFormatter.swift new file mode 100644 index 000000000..c361677a3 --- /dev/null +++ b/Sources/WalletConnectUtils/SIWE/SIWECacaoFormatter.swift @@ -0,0 +1,30 @@ +import Foundation + +public protocol SIWECacaoFormatting { + func formatMessage(from payload: CacaoPayload) throws -> String +} + +public struct SIWECacaoFormatter: SIWECacaoFormatting { + + public init() { } + + public func formatMessage(from payload: CacaoPayload) throws -> String { + let address = try DIDPKH(iss: payload.iss).account.address + let iss = try DIDPKH(iss: payload.iss) + let message = SIWEMessage( + domain: payload.domain, + uri: payload.aud, + address: address, + version: payload.version, + nonce: payload.nonce, + chainId: iss.account.reference, + iat: payload.iat, + nbf: payload.nbf, + exp: payload.exp, + statement: payload.statement, + requestId: payload.requestId, + resources: payload.resources + ) + return message.formatted + } +} diff --git a/Sources/WalletConnectUtils/SIWE/SIWEMessage.swift b/Sources/WalletConnectUtils/SIWE/SIWEMessage.swift new file mode 100644 index 000000000..0a7fc18df --- /dev/null +++ b/Sources/WalletConnectUtils/SIWE/SIWEMessage.swift @@ -0,0 +1,72 @@ +import Foundation + +public struct SIWEMessage: Equatable { + public let domain: String + public let uri: String // aud + public let address: String + public let version: String + public let nonce: String + public let chainId: String + public let iat: String + public let nbf: String? + public let exp: String? + public let statement: String? + public let requestId: String? + public let resources: [String]? + + public init(domain: String, uri: String, address: String, version: String, nonce: String, chainId: String, iat: String, nbf: String?, exp: String?, statement: String?, requestId: String?, resources: [String]?) { + self.domain = domain + self.uri = uri + self.address = address + self.version = version + self.nonce = nonce + self.chainId = chainId + self.iat = iat + self.nbf = nbf + self.exp = exp + self.statement = statement + self.requestId = requestId + self.resources = resources + } + + public var formatted: String { + return """ + \(domain) wants you to sign in with your Ethereum account: + \(address) + \(statementLine) + URI: \(uri) + Version: \(version) + Chain ID: \(chainId) + Nonce: \(nonce) + Issued At: \(iat)\(expLine)\(nbfLine)\(requestIdLine)\(resourcesSection) + """ + } +} + +private extension SIWEMessage { + + var expLine: String { + guard let exp = exp else { return "" } + return "\nExpiration Time: \(exp)" + } + + var statementLine: String { + guard let statement = statement else { return "" } + return "\n\(statement)\n" + } + + var nbfLine: String { + guard let nbf = nbf else { return "" } + return "\nNot Before: \(nbf)" + } + + var requestIdLine: String { + guard let requestId = requestId else { return "" } + return "\nRequest ID: \(requestId)" + } + + var resourcesSection: String { + guard let resources = resources else { return "" } + return resources.reduce("\nResources:") { $0 + "\n- \($1)" } + } +} diff --git a/Tests/AuthTests/AppRespondSubscriberTests.swift b/Tests/AuthTests/AppRespondSubscriberTests.swift index 72f3f4f51..71baa80ef 100644 --- a/Tests/AuthTests/AppRespondSubscriberTests.swift +++ b/Tests/AuthTests/AppRespondSubscriberTests.swift @@ -60,7 +60,7 @@ class AppRespondSubscriberTests: XCTestCase { // subscribe on compromised cacao let account = Account(chainIdentifier: "eip155:1", address: "0x724d0D2DaD3fbB0C168f947B87Fa5DBe36F1A8bf")! let cacaoHeader = CacaoHeader(t: "eip4361") - let cacaoPayload = CacaoPayload(params: compromissedParams.payloadParams, didpkh: DIDPKH(account: account)) + let cacaoPayload = compromissedParams.payloadParams.cacaoPayload(didpkh: DIDPKH(account: account)) let cacaoSignature = CacaoSignature(t: .eip191, s: "") let cacao = Cacao(h: cacaoHeader, p: cacaoPayload, s: cacaoSignature) From 075390ee8067daa12f1dc61344fea37f1056b50b Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Thu, 2 Feb 2023 14:30:39 +0530 Subject: [PATCH 02/17] IdentityNetworkService --- .../AuthenticationService.swift | 12 ---- .../Authentication/IdentityKeyService.swift | 35 +++++++---- .../IdentityNetworkService.swift | 59 +++++++++++++++++++ 3 files changed, 84 insertions(+), 22 deletions(-) delete mode 100644 Sources/Chat/ProtocolServices/Authentication/AuthenticationService.swift create mode 100644 Sources/Chat/ProtocolServices/Authentication/IdentityNetworkService.swift diff --git a/Sources/Chat/ProtocolServices/Authentication/AuthenticationService.swift b/Sources/Chat/ProtocolServices/Authentication/AuthenticationService.swift deleted file mode 100644 index b1dead4ed..000000000 --- a/Sources/Chat/ProtocolServices/Authentication/AuthenticationService.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Foundation - -final class AuthenticationService { - - private let accountService: AccountService - - init(accountService: AccountService) { - self.accountService = accountService - } - - -} diff --git a/Sources/Chat/ProtocolServices/Authentication/IdentityKeyService.swift b/Sources/Chat/ProtocolServices/Authentication/IdentityKeyService.swift index 256eec8c6..131a143df 100644 --- a/Sources/Chat/ProtocolServices/Authentication/IdentityKeyService.swift +++ b/Sources/Chat/ProtocolServices/Authentication/IdentityKeyService.swift @@ -2,37 +2,52 @@ import Foundation enum IdentityKeyAPI: HTTPService { - case register(cacao: String) // TODO: Cacao - case resolve(publicKey: String) + case registerIdentity(cacao: Cacao) + case resolveIdentity(publicKey: String) + case removeIdentity(cacao: Cacao) + case registerInvite(idAuth: String) + case resolveInvite(account: String) + case removeInvite(idAuth: String) var path: String { - return "/identity" + switch self { + case .registerIdentity, .resolveIdentity, .removeIdentity: + return "/identity" + case .registerInvite, .resolveInvite, .removeInvite: + return "/invite" + } } var method: WalletConnectNetworking.HTTPMethod { switch self { - case .register: + case .registerIdentity, .registerInvite: return .post - case .resolve: + case .resolveIdentity, .resolveInvite: return .get + case .removeInvite, .removeIdentity: + return .delete } } var body: Data? { switch self { - case .register(let cacao): + case .registerIdentity(let cacao), .removeIdentity(let cacao): return try? JSONEncoder().encode(cacao) - case .resolve: + case .registerInvite(let idAuth), .removeInvite(let idAuth): + return try? JSONEncoder().encode(["idAuth": idAuth]) + case .resolveIdentity, .resolveInvite: return nil } } var queryParameters: [String : String]? { switch self { - case .register: - return nil - case .resolve(let publicKey): + case .resolveIdentity(let publicKey): return ["publicKey": publicKey] + case .resolveInvite(let account): + return ["account": account] + case .registerIdentity, .registerInvite, .removeInvite, .removeIdentity: + return nil } } } diff --git a/Sources/Chat/ProtocolServices/Authentication/IdentityNetworkService.swift b/Sources/Chat/ProtocolServices/Authentication/IdentityNetworkService.swift new file mode 100644 index 000000000..51e77b1e2 --- /dev/null +++ b/Sources/Chat/ProtocolServices/Authentication/IdentityNetworkService.swift @@ -0,0 +1,59 @@ +import Foundation + +actor IdentityNetworkService { + + private let accountService: AccountService + private let httpService: HTTPClient + + init(accountService: AccountService, httpService: HTTPClient) { + self.accountService = accountService + self.httpService = httpService + } + + // MARK: - IdentityKey + + func registerIdentity(cacao: Cacao) async throws { + let api = IdentityKeyAPI.registerIdentity(cacao: cacao) + try await httpService.request(service: api) + } + + func resolveIdentity(publicKey: String) async throws -> Cacao { + let api = IdentityKeyAPI.resolveIdentity(publicKey: publicKey) + let response = try await httpService.request(ResolveIdentityResponse.self, at: api) + return response.cacao + } + + func removeIdentity(cacao: Cacao) async throws { + let api = IdentityKeyAPI.removeIdentity(cacao: cacao) + try await httpService.request(service: api) + } + + // MARK: - InviteKey + + func registerInvite(idAuth: String) async throws { + let api = IdentityKeyAPI.registerInvite(idAuth: idAuth) + try await httpService.request(service: api) + } + + func resolveInvite(account: String) async throws -> String { + let api = IdentityKeyAPI.resolveInvite(account: account) + let response = try await httpService.request(ResolveInviteResponse.self, at: api) + return response.inviteKey + } + + func removeInvite(idAuth: String) async throws { + let api = IdentityKeyAPI.removeInvite(idAuth: idAuth) + try await httpService.request(service: api) + } +} + +private extension IdentityNetworkService { + + struct ResolveIdentityResponse: Codable { + let cacao: Cacao + } + + struct ResolveInviteResponse: Codable { + let inviteKey: String + } +} From 1dad95bad4d8519efcb321f809b43be235924688 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Thu, 2 Feb 2023 14:46:11 +0530 Subject: [PATCH 03/17] IdentityStorage --- .../AuthenticationStorage.swift | 12 ----- .../Authentication/IdentityStorage.swift | 44 +++++++++++++++++++ 2 files changed, 44 insertions(+), 12 deletions(-) delete mode 100644 Sources/Chat/ProtocolServices/Authentication/AuthenticationStorage.swift create mode 100644 Sources/Chat/ProtocolServices/Authentication/IdentityStorage.swift diff --git a/Sources/Chat/ProtocolServices/Authentication/AuthenticationStorage.swift b/Sources/Chat/ProtocolServices/Authentication/AuthenticationStorage.swift deleted file mode 100644 index f5430e7bf..000000000 --- a/Sources/Chat/ProtocolServices/Authentication/AuthenticationStorage.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Foundation - -typealias IdentityKey = SigningPrivateKey - -final class AuthenticationStorage { - - private let kms: KeychainServiceProtocol - - init(kms: KeychainServiceProtocol) { - self.kms = kms - } -} diff --git a/Sources/Chat/ProtocolServices/Authentication/IdentityStorage.swift b/Sources/Chat/ProtocolServices/Authentication/IdentityStorage.swift new file mode 100644 index 000000000..f8100471b --- /dev/null +++ b/Sources/Chat/ProtocolServices/Authentication/IdentityStorage.swift @@ -0,0 +1,44 @@ +import Foundation + +typealias IdentityKey = SigningPrivateKey +typealias InviteKey = SigningPrivateKey + +final class IdentityStorage { + + private let keychain: KeychainStorageProtocol + + init(keychain: KeychainStorageProtocol) { + self.keychain = keychain + } + + func createIdentityKey(for account: Account) throws -> IdentityKey { + let key = IdentityKey() + try keychain.add(key, forKey: identityKeyIdentifier(for: account)) + return key + } + + func createInviteKey(for account: Account) throws -> InviteKey { + let key = InviteKey() + try keychain.add(key, forKey: inviteKeyIdentifier(for: account)) + return key + } + + func getIdentityKey(for account: Account) -> IdentityKey? { + return try? keychain.read(key: identityKeyIdentifier(for: account)) + } + + func getInviteKey(for account: Account) -> InviteKey? { + return try? keychain.read(key: inviteKeyIdentifier(for: account)) + } +} + +private extension IdentityStorage { + + func identityKeyIdentifier(for account: Account) -> String { + return "com.walletconnect.chat.identity.\(account.absoluteString)" + } + + func inviteKeyIdentifier(for account: Account) -> String { + return "com.walletconnect.chat.invite.\(account.absoluteString)" + } +} From a492d80fbae4bce53ea725a3fb93e52d48281d41 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Thu, 2 Feb 2023 15:55:39 +0530 Subject: [PATCH 04/17] MessageSigner use CacaoPayload --- Example/IntegrationTests/Auth/AuthTests.swift | 3 +- .../Auth/Signer/CacaoSignerTests.swift | 8 ++--- .../AuthRequest/AuthRequestInteractor.swift | 3 +- Sources/Auth/AuthClient.swift | 2 +- Sources/Auth/AuthClientFactory.swift | 2 +- .../Services/App/AppRespondSubscriber.swift | 7 ++--- .../Common/SIWEMessageFormatter.swift | 29 ------------------- .../Auth/Services/Signer/MessageSigner.swift | 12 ++++---- .../Signer/MessageSignerFactory.swift | 2 +- .../Wallet/WalletRespondService.swift | 3 +- Sources/Auth/Types/AuthPayload.swift | 16 ++++++++-- .../IdentityKeyService.swift | 0 .../IdentityNetworkService.swift | 0 .../Identity/IdentityRegisterService.swift | 5 ++++ .../IdentityStorage.swift | 0 .../AuthTests/AppRespondSubscriberTests.swift | 7 ++--- .../Mocks/SIWEMessageFormatterMock.swift | 6 +--- .../AuthTests/SIWEMessageFormatterTests.swift | 20 ++++++------- Tests/AuthTests/Stubs/MessageSignerMock.swift | 3 +- 19 files changed, 52 insertions(+), 76 deletions(-) delete mode 100644 Sources/Auth/Services/Common/SIWEMessageFormatter.swift rename Sources/Chat/ProtocolServices/{Authentication => Identity}/IdentityKeyService.swift (100%) rename Sources/Chat/ProtocolServices/{Authentication => Identity}/IdentityNetworkService.swift (100%) create mode 100644 Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift rename Sources/Chat/ProtocolServices/{Authentication => Identity}/IdentityStorage.swift (100%) diff --git a/Example/IntegrationTests/Auth/AuthTests.swift b/Example/IntegrationTests/Auth/AuthTests.swift index 8bede13a1..436091772 100644 --- a/Example/IntegrationTests/Auth/AuthTests.swift +++ b/Example/IntegrationTests/Auth/AuthTests.swift @@ -83,7 +83,8 @@ final class AuthTests: XCTestCase { Task(priority: .high) { let signerFactory = DefaultSignerFactory() let signer = MessageSignerFactory(signerFactory: signerFactory).create(projectId: InputConfig.projectId) - let signature = try! signer.sign(payload: request.payload, address: walletAccount.address, privateKey: prvKey, type: .eip191) + let payload = try! request.payload.cacaoPayload(address: walletAccount.address) + let signature = try! signer.sign(payload: payload, privateKey: prvKey, type: .eip191) try! await walletAuthClient.respond(requestId: request.id, signature: signature, from: walletAccount) } } diff --git a/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift b/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift index c6481015b..8066c147d 100644 --- a/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift +++ b/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift @@ -45,12 +45,10 @@ class CacaoSignerTest: XCTestCase { func testCacaoSign() throws { let address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" - let formatted = try SIWEMessageFormatter().formatMessage( - from: payload, - address: address - ) + let cacaoPayload = try payload.cacaoPayload(address: address) + let formatted = try SIWECacaoFormatter().formatMessage(from: cacaoPayload) XCTAssertEqual(formatted, message) - XCTAssertEqual(try signer.sign(payload: payload, address: address, privateKey: privateKey, type: .eip191), signature) + XCTAssertEqual(try signer.sign(payload: cacaoPayload, privateKey: privateKey, type: .eip191), signature) } func testCacaoVerify() async throws { diff --git a/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestInteractor.swift index 361d0b8fe..90f554f02 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestInteractor.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestInteractor.swift @@ -8,8 +8,7 @@ final class AuthRequestInteractor { func approve(request: AuthRequest) async throws { let privateKey = Data(hex: "e56da0e170b5e09a8bb8f1b693392c7d56c3739a9c75740fbc558a2877868540") let signature = try signer.sign( - payload: request.payload, - address: account.address, + payload: request.payload.cacaoPayload(address: account.address), privateKey: privateKey, type: .eip191) try await Web3Wallet.instance.respond(requestId: request.id, signature: signature, from: account) diff --git a/Sources/Auth/AuthClient.swift b/Sources/Auth/AuthClient.swift index 9ea611488..f654fb4c9 100644 --- a/Sources/Auth/AuthClient.swift +++ b/Sources/Auth/AuthClient.swift @@ -94,7 +94,7 @@ public class AuthClient: AuthClientProtocol { } public func formatMessage(payload: AuthPayload, address: String) throws -> String { - return try SIWEMessageFormatter().formatMessage(from: payload, address: address) + return try SIWECacaoFormatter().formatMessage(from: payload.cacaoPayload(address: address)) } private func setUpPublishers() { diff --git a/Sources/Auth/AuthClientFactory.swift b/Sources/Auth/AuthClientFactory.swift index 5fc6cb188..f9688eaf6 100644 --- a/Sources/Auth/AuthClientFactory.swift +++ b/Sources/Auth/AuthClientFactory.swift @@ -42,7 +42,7 @@ public struct AuthClientFactory { let kms = KeyManagementService(keychain: keychainStorage) let history = RPCHistoryFactory.createForNetwork(keyValueStorage: keyValueStorage) - let messageFormatter = SIWEMessageFormatter() + 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) diff --git a/Sources/Auth/Services/App/AppRespondSubscriber.swift b/Sources/Auth/Services/App/AppRespondSubscriber.swift index d070880f5..70b48f95a 100644 --- a/Sources/Auth/Services/App/AppRespondSubscriber.swift +++ b/Sources/Auth/Services/App/AppRespondSubscriber.swift @@ -6,7 +6,7 @@ class AppRespondSubscriber { private let logger: ConsoleLogging private let rpcHistory: RPCHistory private let signatureVerifier: MessageSignatureVerifying - private let messageFormatter: SIWEMessageFormatting + private let messageFormatter: SIWECacaoFormatting private let pairingRegisterer: PairingRegisterer private var publishers = [AnyCancellable]() @@ -17,7 +17,7 @@ class AppRespondSubscriber { rpcHistory: RPCHistory, signatureVerifier: MessageSignatureVerifying, pairingRegisterer: PairingRegisterer, - messageFormatter: SIWEMessageFormatting) { + messageFormatter: SIWECacaoFormatting) { self.networkingInteractor = networkingInteractor self.logger = logger self.rpcHistory = rpcHistory @@ -52,8 +52,7 @@ class AppRespondSubscriber { guard let recovered = try? messageFormatter.formatMessage( - from: requestPayload.payloadParams, - address: address + from: requestPayload.payloadParams.cacaoPayload(address: address) ), recovered == message else { self.onResponse?(requestId, .failure(.messageCompromised)); return } diff --git a/Sources/Auth/Services/Common/SIWEMessageFormatter.swift b/Sources/Auth/Services/Common/SIWEMessageFormatter.swift deleted file mode 100644 index 0e4034d5f..000000000 --- a/Sources/Auth/Services/Common/SIWEMessageFormatter.swift +++ /dev/null @@ -1,29 +0,0 @@ -import Foundation - -protocol SIWEMessageFormatting { - func formatMessage(from payload: AuthPayload, address: String) throws -> String - func formatMessage(from payload: CacaoPayload) throws -> String -} - -public struct SIWEMessageFormatter: SIWEMessageFormatting { - - enum Errors: Error { - case invalidChainID - } - - public init() { } - - public func formatMessage(from payload: AuthPayload, address: String) throws -> String { - guard - let blockchain = Blockchain(payload.chainId), - let account = Account(blockchain: blockchain, address: address) else { - throw Errors.invalidChainID - } - let payload = payload.cacaoPayload(didpkh: DIDPKH(account: account)) - return try formatMessage(from: payload) - } - - func formatMessage(from payload: CacaoPayload) throws -> String { - return try SIWECacaoFormatter().formatMessage(from: payload) - } -} diff --git a/Sources/Auth/Services/Signer/MessageSigner.swift b/Sources/Auth/Services/Signer/MessageSigner.swift index 7af8792a2..6b958dec5 100644 --- a/Sources/Auth/Services/Signer/MessageSigner.swift +++ b/Sources/Auth/Services/Signer/MessageSigner.swift @@ -9,8 +9,7 @@ public protocol MessageSignatureVerifying { } public protocol MessageSigning { - func sign(payload: AuthPayload, - address: String, + func sign(payload: CacaoPayload, privateKey: Data, type: CacaoSignatureType ) throws -> CacaoSignature @@ -27,22 +26,21 @@ struct MessageSigner: AuthMessageSigner { private let signer: EthereumSigner private let eip191Verifier: EIP191Verifier private let eip1271Verifier: EIP1271Verifier - private let messageFormatter: SIWEMessageFormatting + private let messageFormatter: SIWECacaoFormatting - init(signer: EthereumSigner, eip191Verifier: EIP191Verifier, eip1271Verifier: EIP1271Verifier, messageFormatter: SIWEMessageFormatting) { + init(signer: EthereumSigner, eip191Verifier: EIP191Verifier, eip1271Verifier: EIP1271Verifier, messageFormatter: SIWECacaoFormatting) { self.signer = signer self.eip191Verifier = eip191Verifier self.eip1271Verifier = eip1271Verifier self.messageFormatter = messageFormatter } - func sign(payload: AuthPayload, - address: String, + func sign(payload: CacaoPayload, privateKey: Data, type: CacaoSignatureType ) throws -> CacaoSignature { - let message = try messageFormatter.formatMessage(from: payload, address: address) + let message = try messageFormatter.formatMessage(from: payload) guard let messageData = message.data(using: .utf8)else { throw Errors.utf8EncodingFailed diff --git a/Sources/Auth/Services/Signer/MessageSignerFactory.swift b/Sources/Auth/Services/Signer/MessageSignerFactory.swift index 88d56d374..60ad7657a 100644 --- a/Sources/Auth/Services/Signer/MessageSignerFactory.swift +++ b/Sources/Auth/Services/Signer/MessageSignerFactory.swift @@ -21,7 +21,7 @@ public struct MessageSignerFactory { httpClient: HTTPNetworkClient(host: "rpc.walletconnect.com"), signer: signerFactory.createEthereumSigner() ), - messageFormatter: SIWEMessageFormatter() + messageFormatter: SIWECacaoFormatter() ) } } diff --git a/Sources/Auth/Services/Wallet/WalletRespondService.swift b/Sources/Auth/Services/Wallet/WalletRespondService.swift index 8ea1946e9..62bb3427a 100644 --- a/Sources/Auth/Services/Wallet/WalletRespondService.swift +++ b/Sources/Auth/Services/Wallet/WalletRespondService.swift @@ -29,9 +29,8 @@ actor WalletRespondService { try kms.setAgreementSecret(keys, topic: topic) - let didpkh = DIDPKH(account: account) let header = CacaoHeader(t: "eip4361") - let payload = authRequestParams.payloadParams.cacaoPayload(didpkh: didpkh) + let payload = try authRequestParams.payloadParams.cacaoPayload(address: account.address) let responseParams = AuthResponseParams(h: header, p: payload, s: signature) let response = RPCResponse(id: requestId, result: responseParams) diff --git a/Sources/Auth/Types/AuthPayload.swift b/Sources/Auth/Types/AuthPayload.swift index 00d8b934b..0e6f7fd1d 100644 --- a/Sources/Auth/Types/AuthPayload.swift +++ b/Sources/Auth/Types/AuthPayload.swift @@ -29,9 +29,14 @@ public struct AuthPayload: Codable, Equatable { self.resources = requestParams.resources } - func cacaoPayload(didpkh: DIDPKH) -> CacaoPayload { + public func cacaoPayload(address: String) throws -> CacaoPayload { + guard + let blockchain = Blockchain(chainId), + let account = Account(blockchain: blockchain, address: address) else { + throw Errors.invalidChainID + } return CacaoPayload( - iss: didpkh.iss, + iss: DIDPKH(account: account).iss, domain: domain, aud: aud, version: version, @@ -45,3 +50,10 @@ public struct AuthPayload: Codable, Equatable { ) } } + +private extension AuthPayload { + + enum Errors: Error { + case invalidChainID + } +} diff --git a/Sources/Chat/ProtocolServices/Authentication/IdentityKeyService.swift b/Sources/Chat/ProtocolServices/Identity/IdentityKeyService.swift similarity index 100% rename from Sources/Chat/ProtocolServices/Authentication/IdentityKeyService.swift rename to Sources/Chat/ProtocolServices/Identity/IdentityKeyService.swift diff --git a/Sources/Chat/ProtocolServices/Authentication/IdentityNetworkService.swift b/Sources/Chat/ProtocolServices/Identity/IdentityNetworkService.swift similarity index 100% rename from Sources/Chat/ProtocolServices/Authentication/IdentityNetworkService.swift rename to Sources/Chat/ProtocolServices/Identity/IdentityNetworkService.swift diff --git a/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift b/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift new file mode 100644 index 000000000..b109d9742 --- /dev/null +++ b/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift @@ -0,0 +1,5 @@ +import Foundation + +actor IdentityRegisterService { + +} diff --git a/Sources/Chat/ProtocolServices/Authentication/IdentityStorage.swift b/Sources/Chat/ProtocolServices/Identity/IdentityStorage.swift similarity index 100% rename from Sources/Chat/ProtocolServices/Authentication/IdentityStorage.swift rename to Sources/Chat/ProtocolServices/Identity/IdentityStorage.swift diff --git a/Tests/AuthTests/AppRespondSubscriberTests.swift b/Tests/AuthTests/AppRespondSubscriberTests.swift index 71baa80ef..e5a64db4b 100644 --- a/Tests/AuthTests/AppRespondSubscriberTests.swift +++ b/Tests/AuthTests/AppRespondSubscriberTests.swift @@ -11,7 +11,7 @@ class AppRespondSubscriberTests: XCTestCase { var networkingInteractor: NetworkingInteractorMock! var sut: AppRespondSubscriber! - var messageFormatter: SIWEMessageFormatter! + var messageFormatter: SIWECacaoFormatter! var rpcHistory: RPCHistory! let defaultTimeout: TimeInterval = 0.01 var messageSigner: AuthMessageSigner! @@ -20,7 +20,7 @@ class AppRespondSubscriberTests: XCTestCase { override func setUp() { networkingInteractor = NetworkingInteractorMock() - messageFormatter = SIWEMessageFormatter() + messageFormatter = SIWECacaoFormatter() messageSigner = MessageSignerMock() rpcHistory = RPCHistoryFactory.createForNetwork(keyValueStorage: RuntimeKeyValueStorage()) pairingStorage = WCPairingStorageMock() @@ -58,9 +58,8 @@ class AppRespondSubscriberTests: XCTestCase { } // subscribe on compromised cacao - let account = Account(chainIdentifier: "eip155:1", address: "0x724d0D2DaD3fbB0C168f947B87Fa5DBe36F1A8bf")! let cacaoHeader = CacaoHeader(t: "eip4361") - let cacaoPayload = compromissedParams.payloadParams.cacaoPayload(didpkh: DIDPKH(account: account)) + let cacaoPayload = try! compromissedParams.payloadParams.cacaoPayload(address: "0x724d0D2DaD3fbB0C168f947B87Fa5DBe36F1A8bf") let cacaoSignature = CacaoSignature(t: .eip191, s: "") let cacao = Cacao(h: cacaoHeader, p: cacaoPayload, s: cacaoSignature) diff --git a/Tests/AuthTests/Mocks/SIWEMessageFormatterMock.swift b/Tests/AuthTests/Mocks/SIWEMessageFormatterMock.swift index 64adc7c96..0796eb6ce 100644 --- a/Tests/AuthTests/Mocks/SIWEMessageFormatterMock.swift +++ b/Tests/AuthTests/Mocks/SIWEMessageFormatterMock.swift @@ -1,13 +1,9 @@ import Foundation @testable import Auth -class SIWEMessageFormatterMock: SIWEMessageFormatting { +class SIWEMessageFormatterMock: SIWECacaoFormatting { var formattedMessage: String! - func formatMessage(from authPayload: AuthPayload, address: String) throws -> String { - return formattedMessage - } - func formatMessage(from payload: CacaoPayload) throws -> String { return formattedMessage } diff --git a/Tests/AuthTests/SIWEMessageFormatterTests.swift b/Tests/AuthTests/SIWEMessageFormatterTests.swift index 859b2cf41..129fe4c52 100644 --- a/Tests/AuthTests/SIWEMessageFormatterTests.swift +++ b/Tests/AuthTests/SIWEMessageFormatterTests.swift @@ -3,11 +3,11 @@ import Foundation import XCTest class SIWEMessageFormatterTests: XCTestCase { - var sut: SIWEMessageFormatter! + var sut: SIWECacaoFormatter! let address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" override func setUp() { - sut = SIWEMessageFormatter() + sut = SIWECacaoFormatter() } func testFormatMessage() throws { @@ -27,7 +27,7 @@ class SIWEMessageFormatterTests: XCTestCase { - ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/ - https://example.com/my-web2-claim.json """ - let message = try sut.formatMessage(from: AuthPayload.stub(), address: address) + let message = try sut.formatMessage(from: AuthPayload.stub().cacaoPayload(address: address)) XCTAssertEqual(message, expectedMessage) } @@ -48,8 +48,9 @@ class SIWEMessageFormatterTests: XCTestCase { """ let message = try sut.formatMessage( from: AuthPayload.stub( - requestParams: RequestParams.stub(statement: nil)), - address: address) + requestParams: RequestParams.stub(statement: nil) + ).cacaoPayload(address: address) + ) XCTAssertEqual(message, expectedMessage) } @@ -69,8 +70,8 @@ class SIWEMessageFormatterTests: XCTestCase { """ let message = try sut.formatMessage( from: AuthPayload.stub( - requestParams: RequestParams.stub(resources: nil)), - address: address) + requestParams: RequestParams.stub(resources: nil)).cacaoPayload(address: address) + ) XCTAssertEqual(message, expectedMessage) } @@ -88,9 +89,8 @@ class SIWEMessageFormatterTests: XCTestCase { """ let message = try sut.formatMessage( from: AuthPayload.stub( - requestParams: RequestParams.stub(statement: nil, - resources: nil)), - address: address) + requestParams: RequestParams.stub(statement: nil, resources: nil)).cacaoPayload(address: address) + ) XCTAssertEqual(message, expectedMessage) } } diff --git a/Tests/AuthTests/Stubs/MessageSignerMock.swift b/Tests/AuthTests/Stubs/MessageSignerMock.swift index 4275cd1b9..bc48a36d6 100644 --- a/Tests/AuthTests/Stubs/MessageSignerMock.swift +++ b/Tests/AuthTests/Stubs/MessageSignerMock.swift @@ -11,8 +11,7 @@ struct MessageSignerMock: AuthMessageSigner { } - func sign(payload: AuthPayload, - address: String, + func sign(payload: CacaoPayload, privateKey: Data, type: CacaoSignatureType ) throws -> CacaoSignature { From 5ff9dcfd33c6e17ea2448c8a3373d83719880e1a Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Thu, 2 Feb 2023 16:25:21 +0530 Subject: [PATCH 05/17] WalletConnectSigner --- Example/ExampleApp.xcodeproj/project.pbxproj | 7 ++ .../xcschemes/WalletConnectSigner.xcscheme | 67 +++++++++++++++++++ .../Auth/Signer/EIP1271VerifierTests.swift | 1 + .../Auth/Signer/EIP191VerifierTests.swift | 1 + Package.swift | 6 ++ Sources/Auth/AuthImports.swift | 1 + Sources/Chat/ChatImports.swift | 2 +- .../Cacao/Cacao.swift | 0 .../Cacao/CacaoHeader.swift | 0 .../Cacao/CacaoPayload.swift | 0 .../Cacao/CacaoSignature.swift | 0 .../DIDPKH/DIDPKH.swift | 0 .../SIWE/SIWECacaoFormatter.swift | 0 .../SIWE/SIWEMessage.swift | 0 .../Ethereum/EIP1271/EIP1271Verifier.swift | 0 .../Signer/Ethereum/EIP1271/RPCService.swift | 0 .../EIP1271/ValidSignatureMethod.swift | 0 .../Ethereum/EIP191/EIP191Verifier.swift | 0 .../Signer}/EthereumSignature.swift | 0 .../Signer}/EthereumSigner.swift | 0 .../Signer/MessageSigner.swift | 4 +- .../Signer/MessageSignerFactory.swift | 4 +- .../Signer/SignerFactory.swift | 0 .../WalletConnectSigner/SignerImports.swift | 3 + .../AuthTests/AppRespondSubscriberTests.swift | 2 +- Tests/AuthTests/Stubs/MessageSignerMock.swift | 2 +- 26 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletConnectSigner.xcscheme rename Sources/{WalletConnectUtils => WalletConnectSigner}/Cacao/Cacao.swift (100%) rename Sources/{WalletConnectUtils => WalletConnectSigner}/Cacao/CacaoHeader.swift (100%) rename Sources/{WalletConnectUtils => WalletConnectSigner}/Cacao/CacaoPayload.swift (100%) rename Sources/{WalletConnectUtils => WalletConnectSigner}/Cacao/CacaoSignature.swift (100%) rename Sources/{WalletConnectUtils => WalletConnectSigner}/DIDPKH/DIDPKH.swift (100%) rename Sources/{WalletConnectUtils => WalletConnectSigner}/SIWE/SIWECacaoFormatter.swift (100%) rename Sources/{WalletConnectUtils => WalletConnectSigner}/SIWE/SIWEMessage.swift (100%) rename Sources/{Auth/Services => WalletConnectSigner}/Signer/Ethereum/EIP1271/EIP1271Verifier.swift (100%) rename Sources/{Auth/Services => WalletConnectSigner}/Signer/Ethereum/EIP1271/RPCService.swift (100%) rename Sources/{Auth/Services => WalletConnectSigner}/Signer/Ethereum/EIP1271/ValidSignatureMethod.swift (100%) rename Sources/{Auth/Services => WalletConnectSigner}/Signer/Ethereum/EIP191/EIP191Verifier.swift (100%) rename Sources/{Auth/Services/Signer/Ethereum => WalletConnectSigner/Signer}/EthereumSignature.swift (100%) rename Sources/{Auth/Services/Signer/Ethereum => WalletConnectSigner/Signer}/EthereumSigner.swift (100%) rename Sources/{Auth/Services => WalletConnectSigner}/Signer/MessageSigner.swift (95%) rename Sources/{Auth/Services => WalletConnectSigner}/Signer/MessageSignerFactory.swift (86%) rename Sources/{Auth/Services => WalletConnectSigner}/Signer/SignerFactory.swift (100%) create mode 100644 Sources/WalletConnectSigner/SignerImports.swift diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index 2982ae6f2..0ca4e2635 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -209,6 +209,7 @@ A5E22D222840C8D300E36487 /* WalletEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E22D212840C8D300E36487 /* WalletEngine.swift */; }; A5E22D242840C8DB00E36487 /* SafariEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E22D232840C8DB00E36487 /* SafariEngine.swift */; }; A5E22D2C2840EAC300E36487 /* XCUIElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E22D2B2840EAC300E36487 /* XCUIElement.swift */; }; + A5F145D7298BCCDD0051B18A /* WalletConnectSigner in Frameworks */ = {isa = PBXBuildFile; productRef = A5F145D6298BCCDD0051B18A /* WalletConnectSigner */; }; C5133A78294125CC00A8314C /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = C5133A77294125CC00A8314C /* Web3 */; }; C53AA4362941251C008EA57C /* DefaultSignerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */; }; C55D347F295DD7140004314A /* AuthRequestModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D347A295DD7140004314A /* AuthRequestModule.swift */; }; @@ -675,6 +676,7 @@ A5C8BE85292FE20B006CC85C /* Web3 in Frameworks */, 84DDB4ED28ABB663003D66ED /* WalletConnectAuth in Frameworks */, C5DD5BE1294E09E3008FD3A4 /* Web3Wallet in Frameworks */, + A5F145D7298BCCDD0051B18A /* WalletConnectSigner in Frameworks */, A5E03E01286466EA00888481 /* WalletConnectChat in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1869,6 +1871,7 @@ 847CF3AE28E3141700F1D760 /* WalletConnectPush */, A5C8BE84292FE20B006CC85C /* Web3 */, C5DD5BE0294E09E3008FD3A4 /* Web3Wallet */, + A5F145D6298BCCDD0051B18A /* WalletConnectSigner */, ); productName = IntegrationTests; productReference = A5E03DED286464DB00888481 /* IntegrationTests.xctest */; @@ -3172,6 +3175,10 @@ isa = XCSwiftPackageProductDependency; productName = WalletConnectChat; }; + A5F145D6298BCCDD0051B18A /* WalletConnectSigner */ = { + isa = XCSwiftPackageProductDependency; + productName = WalletConnectSigner; + }; C5133A77294125CC00A8314C /* Web3 */ = { isa = XCSwiftPackageProductDependency; package = A5AE354528A1A2AC0059AE8A /* XCRemoteSwiftPackageReference "Web3" */; diff --git a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletConnectSigner.xcscheme b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletConnectSigner.xcscheme new file mode 100644 index 000000000..5fadfb8e0 --- /dev/null +++ b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletConnectSigner.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/IntegrationTests/Auth/Signer/EIP1271VerifierTests.swift b/Example/IntegrationTests/Auth/Signer/EIP1271VerifierTests.swift index 45c5c1bdd..40b66bcb4 100644 --- a/Example/IntegrationTests/Auth/Signer/EIP1271VerifierTests.swift +++ b/Example/IntegrationTests/Auth/Signer/EIP1271VerifierTests.swift @@ -1,6 +1,7 @@ import Foundation import XCTest @testable import Auth +@testable import WalletConnectSigner import JSONRPC class EIP1271VerifierTests: XCTestCase { diff --git a/Example/IntegrationTests/Auth/Signer/EIP191VerifierTests.swift b/Example/IntegrationTests/Auth/Signer/EIP191VerifierTests.swift index 2e5c9c1f3..5d5aa2c25 100644 --- a/Example/IntegrationTests/Auth/Signer/EIP191VerifierTests.swift +++ b/Example/IntegrationTests/Auth/Signer/EIP191VerifierTests.swift @@ -1,6 +1,7 @@ import Foundation import XCTest @testable import Auth +@testable import WalletConnectSigner class EIP191VerifierTests: XCTestCase { diff --git a/Package.swift b/Package.swift index c633746d6..214912491 100644 --- a/Package.swift +++ b/Package.swift @@ -43,6 +43,9 @@ let package = Package( .library( name: "Web3Inbox", targets: ["Web3Inbox"]), + .library( + name: "WalletConnectSigner", + targets: ["WalletConnectSigner"]), ], dependencies: [], targets: [ @@ -85,6 +88,9 @@ let package = Package( .target( name: "Web3Inbox", dependencies: ["WalletConnectChat"]), + .target( + name: "WalletConnectSigner", + dependencies: ["WalletConnectNetworking"]), .target( name: "WalletConnectUtils", dependencies: ["JSONRPC"]), diff --git a/Sources/Auth/AuthImports.swift b/Sources/Auth/AuthImports.swift index 27245bda6..f27efa95c 100644 --- a/Sources/Auth/AuthImports.swift +++ b/Sources/Auth/AuthImports.swift @@ -1,3 +1,4 @@ #if !CocoaPods @_exported import WalletConnectPairing +@_exported import WalletConnectSigner #endif diff --git a/Sources/Chat/ChatImports.swift b/Sources/Chat/ChatImports.swift index 23c1738ef..338babe27 100644 --- a/Sources/Chat/ChatImports.swift +++ b/Sources/Chat/ChatImports.swift @@ -1,3 +1,3 @@ #if !CocoaPods -@_exported import WalletConnectNetworking +@_exported import WalletConnectSigner #endif diff --git a/Sources/WalletConnectUtils/Cacao/Cacao.swift b/Sources/WalletConnectSigner/Cacao/Cacao.swift similarity index 100% rename from Sources/WalletConnectUtils/Cacao/Cacao.swift rename to Sources/WalletConnectSigner/Cacao/Cacao.swift diff --git a/Sources/WalletConnectUtils/Cacao/CacaoHeader.swift b/Sources/WalletConnectSigner/Cacao/CacaoHeader.swift similarity index 100% rename from Sources/WalletConnectUtils/Cacao/CacaoHeader.swift rename to Sources/WalletConnectSigner/Cacao/CacaoHeader.swift diff --git a/Sources/WalletConnectUtils/Cacao/CacaoPayload.swift b/Sources/WalletConnectSigner/Cacao/CacaoPayload.swift similarity index 100% rename from Sources/WalletConnectUtils/Cacao/CacaoPayload.swift rename to Sources/WalletConnectSigner/Cacao/CacaoPayload.swift diff --git a/Sources/WalletConnectUtils/Cacao/CacaoSignature.swift b/Sources/WalletConnectSigner/Cacao/CacaoSignature.swift similarity index 100% rename from Sources/WalletConnectUtils/Cacao/CacaoSignature.swift rename to Sources/WalletConnectSigner/Cacao/CacaoSignature.swift diff --git a/Sources/WalletConnectUtils/DIDPKH/DIDPKH.swift b/Sources/WalletConnectSigner/DIDPKH/DIDPKH.swift similarity index 100% rename from Sources/WalletConnectUtils/DIDPKH/DIDPKH.swift rename to Sources/WalletConnectSigner/DIDPKH/DIDPKH.swift diff --git a/Sources/WalletConnectUtils/SIWE/SIWECacaoFormatter.swift b/Sources/WalletConnectSigner/SIWE/SIWECacaoFormatter.swift similarity index 100% rename from Sources/WalletConnectUtils/SIWE/SIWECacaoFormatter.swift rename to Sources/WalletConnectSigner/SIWE/SIWECacaoFormatter.swift diff --git a/Sources/WalletConnectUtils/SIWE/SIWEMessage.swift b/Sources/WalletConnectSigner/SIWE/SIWEMessage.swift similarity index 100% rename from Sources/WalletConnectUtils/SIWE/SIWEMessage.swift rename to Sources/WalletConnectSigner/SIWE/SIWEMessage.swift diff --git a/Sources/Auth/Services/Signer/Ethereum/EIP1271/EIP1271Verifier.swift b/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/EIP1271Verifier.swift similarity index 100% rename from Sources/Auth/Services/Signer/Ethereum/EIP1271/EIP1271Verifier.swift rename to Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/EIP1271Verifier.swift diff --git a/Sources/Auth/Services/Signer/Ethereum/EIP1271/RPCService.swift b/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/RPCService.swift similarity index 100% rename from Sources/Auth/Services/Signer/Ethereum/EIP1271/RPCService.swift rename to Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/RPCService.swift diff --git a/Sources/Auth/Services/Signer/Ethereum/EIP1271/ValidSignatureMethod.swift b/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/ValidSignatureMethod.swift similarity index 100% rename from Sources/Auth/Services/Signer/Ethereum/EIP1271/ValidSignatureMethod.swift rename to Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/ValidSignatureMethod.swift diff --git a/Sources/Auth/Services/Signer/Ethereum/EIP191/EIP191Verifier.swift b/Sources/WalletConnectSigner/Signer/Ethereum/EIP191/EIP191Verifier.swift similarity index 100% rename from Sources/Auth/Services/Signer/Ethereum/EIP191/EIP191Verifier.swift rename to Sources/WalletConnectSigner/Signer/Ethereum/EIP191/EIP191Verifier.swift diff --git a/Sources/Auth/Services/Signer/Ethereum/EthereumSignature.swift b/Sources/WalletConnectSigner/Signer/EthereumSignature.swift similarity index 100% rename from Sources/Auth/Services/Signer/Ethereum/EthereumSignature.swift rename to Sources/WalletConnectSigner/Signer/EthereumSignature.swift diff --git a/Sources/Auth/Services/Signer/Ethereum/EthereumSigner.swift b/Sources/WalletConnectSigner/Signer/EthereumSigner.swift similarity index 100% rename from Sources/Auth/Services/Signer/Ethereum/EthereumSigner.swift rename to Sources/WalletConnectSigner/Signer/EthereumSigner.swift diff --git a/Sources/Auth/Services/Signer/MessageSigner.swift b/Sources/WalletConnectSigner/Signer/MessageSigner.swift similarity index 95% rename from Sources/Auth/Services/Signer/MessageSigner.swift rename to Sources/WalletConnectSigner/Signer/MessageSigner.swift index 6b958dec5..5ecfdf8fa 100644 --- a/Sources/Auth/Services/Signer/MessageSigner.swift +++ b/Sources/WalletConnectSigner/Signer/MessageSigner.swift @@ -15,9 +15,9 @@ public protocol MessageSigning { ) throws -> CacaoSignature } -public typealias AuthMessageSigner = MessageSignatureVerifying & MessageSigning +public typealias CacaoMessageSigner = MessageSignatureVerifying & MessageSigning -struct MessageSigner: AuthMessageSigner { +struct MessageSigner: CacaoMessageSigner { enum Errors: Error { case utf8EncodingFailed diff --git a/Sources/Auth/Services/Signer/MessageSignerFactory.swift b/Sources/WalletConnectSigner/Signer/MessageSignerFactory.swift similarity index 86% rename from Sources/Auth/Services/Signer/MessageSignerFactory.swift rename to Sources/WalletConnectSigner/Signer/MessageSignerFactory.swift index 60ad7657a..ef4f53879 100644 --- a/Sources/Auth/Services/Signer/MessageSignerFactory.swift +++ b/Sources/WalletConnectSigner/Signer/MessageSignerFactory.swift @@ -8,11 +8,11 @@ public struct MessageSignerFactory { self.signerFactory = signerFactory } - public func create() -> AuthMessageSigner { + public func create() -> CacaoMessageSigner { return create(projectId: Networking.projectId) } - func create(projectId: String) -> AuthMessageSigner { + public func create(projectId: String) -> CacaoMessageSigner { return MessageSigner( signer: signerFactory.createEthereumSigner(), eip191Verifier: EIP191Verifier(signer: signerFactory.createEthereumSigner()), diff --git a/Sources/Auth/Services/Signer/SignerFactory.swift b/Sources/WalletConnectSigner/Signer/SignerFactory.swift similarity index 100% rename from Sources/Auth/Services/Signer/SignerFactory.swift rename to Sources/WalletConnectSigner/Signer/SignerFactory.swift diff --git a/Sources/WalletConnectSigner/SignerImports.swift b/Sources/WalletConnectSigner/SignerImports.swift new file mode 100644 index 000000000..23c1738ef --- /dev/null +++ b/Sources/WalletConnectSigner/SignerImports.swift @@ -0,0 +1,3 @@ +#if !CocoaPods +@_exported import WalletConnectNetworking +#endif diff --git a/Tests/AuthTests/AppRespondSubscriberTests.swift b/Tests/AuthTests/AppRespondSubscriberTests.swift index e5a64db4b..473ea5d1d 100644 --- a/Tests/AuthTests/AppRespondSubscriberTests.swift +++ b/Tests/AuthTests/AppRespondSubscriberTests.swift @@ -14,7 +14,7 @@ class AppRespondSubscriberTests: XCTestCase { var messageFormatter: SIWECacaoFormatter! var rpcHistory: RPCHistory! let defaultTimeout: TimeInterval = 0.01 - var messageSigner: AuthMessageSigner! + var messageSigner: CacaoMessageSigner! var pairingStorage: WCPairingStorageMock! var pairingRegisterer: PairingRegistererMock! diff --git a/Tests/AuthTests/Stubs/MessageSignerMock.swift b/Tests/AuthTests/Stubs/MessageSignerMock.swift index bc48a36d6..1d3cf358d 100644 --- a/Tests/AuthTests/Stubs/MessageSignerMock.swift +++ b/Tests/AuthTests/Stubs/MessageSignerMock.swift @@ -1,7 +1,7 @@ import Foundation import Auth -struct MessageSignerMock: AuthMessageSigner { +struct MessageSignerMock: CacaoMessageSigner { func verify(signature: CacaoSignature, message: String, From ad20fc09956baaae3b71d5b733ff03a0e586070a Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Thu, 2 Feb 2023 17:23:14 +0530 Subject: [PATCH 06/17] IdentityRegisterService --- .../Auth/Services/Common/IATProvider.swift | 11 ---- .../Identity/IdentityRegisterService.swift | 60 ++++++++++++++++++- .../Identity/IdentityStorage.swift | 8 +-- .../ClientAuth/DIDKeyFactory.swift | 8 ++- .../Cacao/IATProvider.swift | 14 +++++ 5 files changed, 80 insertions(+), 21 deletions(-) delete mode 100644 Sources/Auth/Services/Common/IATProvider.swift create mode 100644 Sources/WalletConnectSigner/Cacao/IATProvider.swift diff --git a/Sources/Auth/Services/Common/IATProvider.swift b/Sources/Auth/Services/Common/IATProvider.swift deleted file mode 100644 index 1d386c11e..000000000 --- a/Sources/Auth/Services/Common/IATProvider.swift +++ /dev/null @@ -1,11 +0,0 @@ -import Foundation - -protocol IATProvider { - var iat: String { get } -} - -struct DefaultIATProvider: IATProvider { - var iat: String { - return ISO8601DateFormatter().string(from: Date()) - } -} diff --git a/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift b/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift index b109d9742..34daae0a3 100644 --- a/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift +++ b/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift @@ -1,5 +1,63 @@ import Foundation actor IdentityRegisterService { - + + private let keyserverURL: URL + private let identityStorage: IdentityStorage + private let identityNetworkService: IdentityNetworkService + private let iatProvader: IATProvider + private let messageFormatter: SIWECacaoFormatting + + init( + keyserverURL: URL, + identityStorage: IdentityStorage, + identityNetworkService: IdentityNetworkService, + iatProvader: IATProvider, + messageFormatter: SIWECacaoFormatting + ) { + self.keyserverURL = keyserverURL + self.identityStorage = identityStorage + self.identityNetworkService = identityNetworkService + self.iatProvader = iatProvader + self.messageFormatter = messageFormatter + } + + func register(account: Account, isPrivate: Bool, onSign: (String) -> CacaoSignature) async throws -> String { + if let identityKey = identityStorage.getIdentityKey(for: account) { + return identityKey.publicKey.hexRepresentation + } + + let identityKey = IdentityKey() + let identityPublicKey = identityKey.publicKey + let identityKeyDID = ED25519DIDKeyFactory().make( + pubKey: identityPublicKey.rawRepresentation, prefix: true + ) + let cacaoHeader = CacaoHeader(t: "eip4361") + let cacaoPayload = makeCacaoPayload(identityKeyDID: identityKeyDID, account: account) + let cacaoSignature = onSign(try messageFormatter.formatMessage(from: cacaoPayload)) + + let cacao = Cacao(h: cacaoHeader, p: cacaoPayload, s: cacaoSignature) + try await identityNetworkService.registerIdentity(cacao: cacao) + + // TODO: Handle private mode + + try identityStorage.saveIdentityKey(identityKey, for: account) + return identityPublicKey.hexRepresentation + } +} + +private extension IdentityRegisterService { + + func makeCacaoPayload(identityKeyDID: String, account: Account) -> CacaoPayload { + return CacaoPayload( + iss: DIDPKH(account: account).iss, + domain: keyserverURL.host!, + aud: keyserverURL.absoluteString, + version: "1", + nonce: Data.randomBytes(count: 32).toHexString(), + iat: iatProvader.iat, + nbf: nil, exp: nil, statement: nil, requestId: nil, + resources: [identityKeyDID] + ) + } } diff --git a/Sources/Chat/ProtocolServices/Identity/IdentityStorage.swift b/Sources/Chat/ProtocolServices/Identity/IdentityStorage.swift index f8100471b..db1d873f0 100644 --- a/Sources/Chat/ProtocolServices/Identity/IdentityStorage.swift +++ b/Sources/Chat/ProtocolServices/Identity/IdentityStorage.swift @@ -11,16 +11,12 @@ final class IdentityStorage { self.keychain = keychain } - func createIdentityKey(for account: Account) throws -> IdentityKey { - let key = IdentityKey() + func saveIdentityKey(_ key: IdentityKey, for account: Account) throws { try keychain.add(key, forKey: identityKeyIdentifier(for: account)) - return key } - func createInviteKey(for account: Account) throws -> InviteKey { - let key = InviteKey() + func saveInviteKey(_ key: InviteKey, for account: Account) throws { try keychain.add(key, forKey: inviteKeyIdentifier(for: account)) - return key } func getIdentityKey(for account: Account) -> IdentityKey? { diff --git a/Sources/WalletConnectRelay/ClientAuth/DIDKeyFactory.swift b/Sources/WalletConnectRelay/ClientAuth/DIDKeyFactory.swift index 2a062c090..1d3bb7066 100644 --- a/Sources/WalletConnectRelay/ClientAuth/DIDKeyFactory.swift +++ b/Sources/WalletConnectRelay/ClientAuth/DIDKeyFactory.swift @@ -1,19 +1,21 @@ import Foundation -protocol DIDKeyFactory { +public protocol DIDKeyFactory { func make(pubKey: Data, prefix: Bool) -> String } /// A DID Method for Static Cryptographic Keys /// did-key-format := did:key:MULTIBASE(base58-btc, MULTICODEC(public-key-type, raw-public-key-bytes)) -struct ED25519DIDKeyFactory: DIDKeyFactory { +public struct ED25519DIDKeyFactory: DIDKeyFactory { private let DID_DELIMITER = ":" private let DID_PREFIX = "did" private let DID_METHOD = "key" private let MULTICODEC_ED25519_HEADER: [UInt8] = [0xed, 0x01] private let MULTICODEC_ED25519_BASE = "z" - func make(pubKey: Data, prefix: Bool) -> String { + public init() { } + + public func make(pubKey: Data, prefix: Bool) -> String { let multibase = multibase(pubKey: pubKey) guard prefix else { return multibase } diff --git a/Sources/WalletConnectSigner/Cacao/IATProvider.swift b/Sources/WalletConnectSigner/Cacao/IATProvider.swift new file mode 100644 index 000000000..22aefa45d --- /dev/null +++ b/Sources/WalletConnectSigner/Cacao/IATProvider.swift @@ -0,0 +1,14 @@ +import Foundation + +public protocol IATProvider { + var iat: String { get } +} + +public struct DefaultIATProvider: IATProvider { + + public init() { } + + public var iat: String { + return ISO8601DateFormatter().string(from: Date()) + } +} From 015b7fd5744b0607f2c25ae7b348ab342ac34544 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Thu, 2 Feb 2023 19:23:12 +0530 Subject: [PATCH 07/17] WalletConnectSigner scheme --- .../xcshareddata/xcschemes/WalletConnectSigner.xcscheme | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletConnectSigner.xcscheme b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletConnectSigner.xcscheme index 5fadfb8e0..7d2425bad 100644 --- a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletConnectSigner.xcscheme +++ b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletConnectSigner.xcscheme @@ -17,7 +17,7 @@ BlueprintIdentifier = "WalletConnectSigner" BuildableName = "WalletConnectSigner" BlueprintName = "WalletConnectSigner" - ReferencedContainer = "container:"> + ReferencedContainer = "container:.."> @@ -53,7 +53,7 @@ BlueprintIdentifier = "WalletConnectSigner" BuildableName = "WalletConnectSigner" BlueprintName = "WalletConnectSigner" - ReferencedContainer = "container:"> + ReferencedContainer = "container:.."> From c107d3c6850278b09e36c5c36c2ab57c3c223312 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Fri, 3 Feb 2023 18:32:26 +0530 Subject: [PATCH 08/17] Account removed from getPendingRequests --- Sources/Auth/AuthClient.swift | 4 ++-- Sources/Auth/AuthClientProtocol.swift | 2 +- Sources/Auth/Services/Wallet/PendingRequestsProvider.swift | 2 +- Sources/Web3Wallet/Web3WalletClient.swift | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Sources/Auth/AuthClient.swift b/Sources/Auth/AuthClient.swift index f654fb4c9..2ab5e242a 100644 --- a/Sources/Auth/AuthClient.swift +++ b/Sources/Auth/AuthClient.swift @@ -89,8 +89,8 @@ public class AuthClient: AuthClientProtocol { /// Query pending authentication requests /// - Returns: Pending authentication requests - public func getPendingRequests(account: Account) throws -> [AuthRequest] { - return try pendingRequestsProvider.getPendingRequests(account: account) + public func getPendingRequests() throws -> [AuthRequest] { + return try pendingRequestsProvider.getPendingRequests() } public func formatMessage(payload: AuthPayload, address: String) throws -> String { diff --git a/Sources/Auth/AuthClientProtocol.swift b/Sources/Auth/AuthClientProtocol.swift index 9e1a1fb62..31413cb76 100644 --- a/Sources/Auth/AuthClientProtocol.swift +++ b/Sources/Auth/AuthClientProtocol.swift @@ -7,5 +7,5 @@ public protocol AuthClientProtocol { func formatMessage(payload: AuthPayload, address: String) throws -> String func respond(requestId: RPCID, signature: CacaoSignature, from account: Account) async throws func reject(requestId: RPCID) async throws - func getPendingRequests(account: Account) throws -> [AuthRequest] + func getPendingRequests() throws -> [AuthRequest] } diff --git a/Sources/Auth/Services/Wallet/PendingRequestsProvider.swift b/Sources/Auth/Services/Wallet/PendingRequestsProvider.swift index 4aa8c04c0..524c029d5 100644 --- a/Sources/Auth/Services/Wallet/PendingRequestsProvider.swift +++ b/Sources/Auth/Services/Wallet/PendingRequestsProvider.swift @@ -7,7 +7,7 @@ class PendingRequestsProvider { self.rpcHistory = rpcHistory } - public func getPendingRequests(account: Account) throws -> [AuthRequest] { + public func getPendingRequests() throws -> [AuthRequest] { let pendingRequests: [AuthRequest] = rpcHistory.getPending() .filter {$0.request.method == "wc_authRequest"} .compactMap { diff --git a/Sources/Web3Wallet/Web3WalletClient.swift b/Sources/Web3Wallet/Web3WalletClient.swift index 43c709b95..d9397de4e 100644 --- a/Sources/Web3Wallet/Web3WalletClient.swift +++ b/Sources/Web3Wallet/Web3WalletClient.swift @@ -169,7 +169,7 @@ public class Web3WalletClient { /// Query pending authentication requests /// - Returns: Pending authentication requests - public func getPendingRequests(account: Account) throws -> [AuthRequest] { - try authClient.getPendingRequests(account: account) + public func getPendingRequests() throws -> [AuthRequest] { + try authClient.getPendingRequests() } } From 877a6c552f0da68bf21355450edd22a1f67ccad2 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Mon, 6 Feb 2023 17:18:24 +0530 Subject: [PATCH 09/17] registerInvite implemented --- .../xcschemes/WalletConnectJWT.xcscheme | 67 +++++++++++++ Package.swift | 12 ++- .../Identity/IdentityKey.swift | 3 + .../Identity/IdentityRegisterService.swift | 93 +++++++++++++++---- .../Identity/IdentityStorage.swift | 7 +- .../JWT => WalletConnectJWT}/JWT+Claims.swift | 1 + .../JWT => WalletConnectJWT}/JWT+Header.swift | 0 .../JWT => WalletConnectJWT}/JWT.swift | 4 +- .../JWT => WalletConnectJWT}/JWTEncoder.swift | 0 Sources/WalletConnectJWT/JWTFactory.swift | 28 ++++++ Sources/WalletConnectJWT/JWTImports.swift | 3 + .../JWT => WalletConnectJWT}/JWTSigning.swift | 0 .../SigningKeyCryptoKit.swift | 6 ++ .../ClientAuth/SocketAuthenticator.swift | 22 ++--- Sources/WalletConnectRelay/RelayImports.swift | 2 +- .../Cacao/Cacao.swift | 0 .../Cacao/CacaoHeader.swift | 0 .../Cacao/CacaoPayload.swift | 0 .../Cacao/CacaoSignature.swift | 0 .../Cacao/IATProvider.swift | 0 .../DID}/Base58.swift | 0 .../DID}/DIDKeyFactory.swift | 0 .../DID}/DIDPKH.swift | 7 ++ .../SIWE/SIWECacaoFormatter.swift | 0 .../SIWE/SIWEMessage.swift | 0 25 files changed, 213 insertions(+), 42 deletions(-) create mode 100644 Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletConnectJWT.xcscheme create mode 100644 Sources/Chat/ProtocolServices/Identity/IdentityKey.swift rename Sources/{WalletConnectRelay/ClientAuth/JWT => WalletConnectJWT}/JWT+Claims.swift (95%) rename Sources/{WalletConnectRelay/ClientAuth/JWT => WalletConnectJWT}/JWT+Header.swift (100%) rename Sources/{WalletConnectRelay/ClientAuth/JWT => WalletConnectJWT}/JWT.swift (85%) rename Sources/{WalletConnectRelay/ClientAuth/JWT => WalletConnectJWT}/JWTEncoder.swift (100%) create mode 100644 Sources/WalletConnectJWT/JWTFactory.swift create mode 100644 Sources/WalletConnectJWT/JWTImports.swift rename Sources/{WalletConnectRelay/ClientAuth/JWT => WalletConnectJWT}/JWTSigning.swift (100%) rename Sources/{WalletConnectSigner => WalletConnectUtils}/Cacao/Cacao.swift (100%) rename Sources/{WalletConnectSigner => WalletConnectUtils}/Cacao/CacaoHeader.swift (100%) rename Sources/{WalletConnectSigner => WalletConnectUtils}/Cacao/CacaoPayload.swift (100%) rename Sources/{WalletConnectSigner => WalletConnectUtils}/Cacao/CacaoSignature.swift (100%) rename Sources/{WalletConnectSigner => WalletConnectUtils}/Cacao/IATProvider.swift (100%) rename Sources/{WalletConnectRelay/ClientAuth => WalletConnectUtils/DID}/Base58.swift (100%) rename Sources/{WalletConnectRelay/ClientAuth => WalletConnectUtils/DID}/DIDKeyFactory.swift (100%) rename Sources/{WalletConnectSigner/DIDPKH => WalletConnectUtils/DID}/DIDPKH.swift (88%) rename Sources/{WalletConnectSigner => WalletConnectUtils}/SIWE/SIWECacaoFormatter.swift (100%) rename Sources/{WalletConnectSigner => WalletConnectUtils}/SIWE/SIWEMessage.swift (100%) diff --git a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletConnectJWT.xcscheme b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletConnectJWT.xcscheme new file mode 100644 index 000000000..0bfec5ddc --- /dev/null +++ b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletConnectJWT.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Package.swift b/Package.swift index 214912491..9455df255 100644 --- a/Package.swift +++ b/Package.swift @@ -43,6 +43,11 @@ let package = Package( .library( name: "Web3Inbox", targets: ["Web3Inbox"]), + // TODO: Remove library + .library( + name: "WalletConnectJWT", + targets: ["WalletConnectJWT"]), + // TODO: Remove library .library( name: "WalletConnectSigner", targets: ["WalletConnectSigner"]), @@ -59,7 +64,7 @@ let package = Package( path: "Sources/Chat"), .target( name: "Auth", - dependencies: ["WalletConnectPairing"], + dependencies: ["WalletConnectPairing", "WalletConnectSigner"], path: "Sources/Auth"), .target( name: "Web3Wallet", @@ -75,7 +80,7 @@ let package = Package( path: "Sources/WalletConnectEcho"), .target( name: "WalletConnectRelay", - dependencies: ["WalletConnectKMS"], + dependencies: ["WalletConnectJWT"], path: "Sources/WalletConnectRelay", resources: [.copy("PackageConfig.json")]), .target( @@ -91,6 +96,9 @@ let package = Package( .target( name: "WalletConnectSigner", dependencies: ["WalletConnectNetworking"]), + .target( + name: "WalletConnectJWT", + dependencies: ["WalletConnectKMS"]), .target( name: "WalletConnectUtils", dependencies: ["JSONRPC"]), diff --git a/Sources/Chat/ProtocolServices/Identity/IdentityKey.swift b/Sources/Chat/ProtocolServices/Identity/IdentityKey.swift new file mode 100644 index 000000000..b172afbdb --- /dev/null +++ b/Sources/Chat/ProtocolServices/Identity/IdentityKey.swift @@ -0,0 +1,3 @@ +import Foundation + +typealias IdentityKey = SigningPrivateKey diff --git a/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift b/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift index 34daae0a3..68353adfe 100644 --- a/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift +++ b/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift @@ -22,42 +22,99 @@ actor IdentityRegisterService { self.messageFormatter = messageFormatter } - func register(account: Account, isPrivate: Bool, onSign: (String) -> CacaoSignature) async throws -> String { + func registerIdentity(account: Account, + isPrivate: Bool, + onSign: (String) -> CacaoSignature + ) async throws -> String { + if let identityKey = identityStorage.getIdentityKey(for: account) { return identityKey.publicKey.hexRepresentation } let identityKey = IdentityKey() - let identityPublicKey = identityKey.publicKey - let identityKeyDID = ED25519DIDKeyFactory().make( - pubKey: identityPublicKey.rawRepresentation, prefix: true - ) - let cacaoHeader = CacaoHeader(t: "eip4361") - let cacaoPayload = makeCacaoPayload(identityKeyDID: identityKeyDID, account: account) - let cacaoSignature = onSign(try messageFormatter.formatMessage(from: cacaoPayload)) - - let cacao = Cacao(h: cacaoHeader, p: cacaoPayload, s: cacaoSignature) + let cacao = try makeCacao(DIDKey: identityKey.DIDKey, account: account, onSign: onSign) try await identityNetworkService.registerIdentity(cacao: cacao) // TODO: Handle private mode try identityStorage.saveIdentityKey(identityKey, for: account) - return identityPublicKey.hexRepresentation + return identityKey.publicKey.hexRepresentation + } + + func registerInvite(account: Account, + isPrivate: Bool, + onSign: (String) -> CacaoSignature + ) async throws -> String { + + if let inviteKey = identityStorage.getInviteKey(for: account) { + return inviteKey.publicKey.hexRepresentation + } + + let inviteKey = IdentityKey() + try await identityNetworkService.registerInvite(idAuth: makeIDAuth( + account: account, + publicKeyString: inviteKey.publicKey.hexRepresentation + )) + + try identityStorage.saveIdentityKey(inviteKey, for: account) + return inviteKey.publicKey.hexRepresentation } } private extension IdentityRegisterService { - func makeCacaoPayload(identityKeyDID: String, account: Account) -> CacaoPayload { - return CacaoPayload( - iss: DIDPKH(account: account).iss, + enum Errors: Error { + case identityKeyNotFound + } + + func makeCacao( + DIDKey: String, + account: Account, + onSign: (String) -> CacaoSignature + ) throws -> Cacao { + let cacaoHeader = CacaoHeader(t: "eip4361") + let cacaoPayload = CacaoPayload( + iss: account.iss, domain: keyserverURL.host!, - aud: keyserverURL.absoluteString, - version: "1", - nonce: Data.randomBytes(count: 32).toHexString(), + aud: getAudience(), + version: getVersion(), + nonce: getNonce(), iat: iatProvader.iat, nbf: nil, exp: nil, statement: nil, requestId: nil, - resources: [identityKeyDID] + resources: [DIDKey] ) + let cacaoSignature = onSign(try messageFormatter.formatMessage(from: cacaoPayload)) + return Cacao(h: cacaoHeader, p: cacaoPayload, s: cacaoSignature) + } + + func makeIDAuth(account: Account, publicKeyString: String) throws -> String { + guard let inviteKey = identityStorage.getInviteKey(for: account) + else { throw Errors.identityKeyNotFound } + + return try JWTFactory().createAndSignJWT( + keyPair: inviteKey, + aud: getAudience(), + exp: getExpiry(), + pkh: account.iss + ) + } + + private func getNonce() -> String { + return Data.randomBytes(count: 32).toHexString() + } + + private func getVersion() -> String { + return "1" + } + + private func getExpiry() -> Int { + var components = DateComponents() + components.setValue(1, for: .hour) + let date = Calendar.current.date(byAdding: components, to: Date())! + return Int(date.timeIntervalSince1970) + } + + private func getAudience() -> String { + return keyserverURL.absoluteString } } diff --git a/Sources/Chat/ProtocolServices/Identity/IdentityStorage.swift b/Sources/Chat/ProtocolServices/Identity/IdentityStorage.swift index db1d873f0..7f93bb075 100644 --- a/Sources/Chat/ProtocolServices/Identity/IdentityStorage.swift +++ b/Sources/Chat/ProtocolServices/Identity/IdentityStorage.swift @@ -1,8 +1,5 @@ import Foundation -typealias IdentityKey = SigningPrivateKey -typealias InviteKey = SigningPrivateKey - final class IdentityStorage { private let keychain: KeychainStorageProtocol @@ -15,7 +12,7 @@ final class IdentityStorage { try keychain.add(key, forKey: identityKeyIdentifier(for: account)) } - func saveInviteKey(_ key: InviteKey, for account: Account) throws { + func saveInviteKey(_ key: IdentityKey, for account: Account) throws { try keychain.add(key, forKey: inviteKeyIdentifier(for: account)) } @@ -23,7 +20,7 @@ final class IdentityStorage { return try? keychain.read(key: identityKeyIdentifier(for: account)) } - func getInviteKey(for account: Account) -> InviteKey? { + func getInviteKey(for account: Account) -> IdentityKey? { return try? keychain.read(key: inviteKeyIdentifier(for: account)) } } diff --git a/Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Claims.swift b/Sources/WalletConnectJWT/JWT+Claims.swift similarity index 95% rename from Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Claims.swift rename to Sources/WalletConnectJWT/JWT+Claims.swift index 14ea4cffd..125a2b50a 100644 --- a/Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Claims.swift +++ b/Sources/WalletConnectJWT/JWT+Claims.swift @@ -7,6 +7,7 @@ extension JWT { let aud: String let iat: Int let exp: Int + let pkh: String? func encode() throws -> String { let jsonEncoder = JSONEncoder() diff --git a/Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Header.swift b/Sources/WalletConnectJWT/JWT+Header.swift similarity index 100% rename from Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Header.swift rename to Sources/WalletConnectJWT/JWT+Header.swift diff --git a/Sources/WalletConnectRelay/ClientAuth/JWT/JWT.swift b/Sources/WalletConnectJWT/JWT.swift similarity index 85% rename from Sources/WalletConnectRelay/ClientAuth/JWT/JWT.swift rename to Sources/WalletConnectJWT/JWT.swift index 17663319b..7633fb991 100644 --- a/Sources/WalletConnectRelay/ClientAuth/JWT/JWT.swift +++ b/Sources/WalletConnectJWT/JWT.swift @@ -9,12 +9,12 @@ struct JWT: Codable, Equatable { var claims: Claims var signature: String? - public init(header: Header = Header(), claims: Claims) { + init(header: Header = Header(), claims: Claims) { self.header = header self.claims = claims } - public mutating func sign(using jwtSigner: JWTSigning) throws { + mutating func sign(using jwtSigner: JWTSigning) throws { header.alg = jwtSigner.alg let headerString = try header.encode() let claimsString = try claims.encode() diff --git a/Sources/WalletConnectRelay/ClientAuth/JWT/JWTEncoder.swift b/Sources/WalletConnectJWT/JWTEncoder.swift similarity index 100% rename from Sources/WalletConnectRelay/ClientAuth/JWT/JWTEncoder.swift rename to Sources/WalletConnectJWT/JWTEncoder.swift diff --git a/Sources/WalletConnectJWT/JWTFactory.swift b/Sources/WalletConnectJWT/JWTFactory.swift new file mode 100644 index 000000000..17a04e124 --- /dev/null +++ b/Sources/WalletConnectJWT/JWTFactory.swift @@ -0,0 +1,28 @@ +import Foundation + +public struct JWTFactory { + + public init() { } + + public func createAndSignJWT( + keyPair: SigningPrivateKey, + aud: String, + exp: Int, + pkh: String? + ) throws -> String { + let now = Int(Date().timeIntervalSince1970) + let iss = keyPair.DIDKey + let sub = generateSubject() + let claims = JWT.Claims(iss: iss, sub: sub, aud: aud, iat: now, exp: exp, pkh: pkh) + var jwt = JWT(claims: claims) + try jwt.sign(using: EdDSASigner(keyPair)) + return try jwt.encoded() + } +} + +private extension JWTFactory { + + private func generateSubject() -> String { + return Data.randomBytes(count: 32).toHexString() + } +} diff --git a/Sources/WalletConnectJWT/JWTImports.swift b/Sources/WalletConnectJWT/JWTImports.swift new file mode 100644 index 000000000..24d4a8cab --- /dev/null +++ b/Sources/WalletConnectJWT/JWTImports.swift @@ -0,0 +1,3 @@ +#if !CocoaPods +@_exported import WalletConnectKMS +#endif diff --git a/Sources/WalletConnectRelay/ClientAuth/JWT/JWTSigning.swift b/Sources/WalletConnectJWT/JWTSigning.swift similarity index 100% rename from Sources/WalletConnectRelay/ClientAuth/JWT/JWTSigning.swift rename to Sources/WalletConnectJWT/JWTSigning.swift diff --git a/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/SigningKeyCryptoKit.swift b/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/SigningKeyCryptoKit.swift index f02cc72cb..527463fed 100644 --- a/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/SigningKeyCryptoKit.swift +++ b/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/SigningKeyCryptoKit.swift @@ -79,4 +79,10 @@ public struct SigningPrivateKey: GenericPasswordConvertible, Equatable { public func signature(_ data: Data) throws -> Data { return try key.signature(for: data) } + + public var DIDKey: String { + return ED25519DIDKeyFactory().make( + pubKey: publicKey.rawRepresentation, prefix: true + ) + } } diff --git a/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift b/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift index 6858dcad5..1cfe42174 100644 --- a/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift +++ b/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift @@ -17,25 +17,19 @@ struct SocketAuthenticator: SocketAuthenticating { func createAuthToken() throws -> String { let clientIdKeyPair = try clientIdStorage.getOrCreateKeyPair() - let subject = generateSubject() - return try createAndSignJWT(subject: subject, keyPair: clientIdKeyPair) + return try createAndSignJWT(keyPair: clientIdKeyPair) } - private func createAndSignJWT(subject: String, keyPair: SigningPrivateKey) throws -> String { - let issuer = didKeyFactory.make(pubKey: keyPair.publicKey.rawRepresentation, prefix: true) - let now = Int(Date().timeIntervalSince1970) - let claims = JWT.Claims(iss: issuer, sub: subject, aud: getAudience(), iat: now, exp: getExpiry()) - var jwt = JWT(claims: claims) - try jwt.sign(using: EdDSASigner(keyPair)) - return try jwt.encoded() - } - - private func generateSubject() -> String { - return Data.randomBytes(count: 32).toHexString() + private func createAndSignJWT(keyPair: SigningPrivateKey) throws -> String { + return try JWTFactory().createAndSignJWT( + keyPair: keyPair, + aud: getAudience(), + exp: getExpiry(), + pkh: nil + ) } private func getExpiry() -> Int { - var components = DateComponents() components.setValue(1, for: .day) // safe to unwrap as the date must be calculated diff --git a/Sources/WalletConnectRelay/RelayImports.swift b/Sources/WalletConnectRelay/RelayImports.swift index 24d4a8cab..5c5e68a01 100644 --- a/Sources/WalletConnectRelay/RelayImports.swift +++ b/Sources/WalletConnectRelay/RelayImports.swift @@ -1,3 +1,3 @@ #if !CocoaPods -@_exported import WalletConnectKMS +@_exported import WalletConnectJWT #endif diff --git a/Sources/WalletConnectSigner/Cacao/Cacao.swift b/Sources/WalletConnectUtils/Cacao/Cacao.swift similarity index 100% rename from Sources/WalletConnectSigner/Cacao/Cacao.swift rename to Sources/WalletConnectUtils/Cacao/Cacao.swift diff --git a/Sources/WalletConnectSigner/Cacao/CacaoHeader.swift b/Sources/WalletConnectUtils/Cacao/CacaoHeader.swift similarity index 100% rename from Sources/WalletConnectSigner/Cacao/CacaoHeader.swift rename to Sources/WalletConnectUtils/Cacao/CacaoHeader.swift diff --git a/Sources/WalletConnectSigner/Cacao/CacaoPayload.swift b/Sources/WalletConnectUtils/Cacao/CacaoPayload.swift similarity index 100% rename from Sources/WalletConnectSigner/Cacao/CacaoPayload.swift rename to Sources/WalletConnectUtils/Cacao/CacaoPayload.swift diff --git a/Sources/WalletConnectSigner/Cacao/CacaoSignature.swift b/Sources/WalletConnectUtils/Cacao/CacaoSignature.swift similarity index 100% rename from Sources/WalletConnectSigner/Cacao/CacaoSignature.swift rename to Sources/WalletConnectUtils/Cacao/CacaoSignature.swift diff --git a/Sources/WalletConnectSigner/Cacao/IATProvider.swift b/Sources/WalletConnectUtils/Cacao/IATProvider.swift similarity index 100% rename from Sources/WalletConnectSigner/Cacao/IATProvider.swift rename to Sources/WalletConnectUtils/Cacao/IATProvider.swift diff --git a/Sources/WalletConnectRelay/ClientAuth/Base58.swift b/Sources/WalletConnectUtils/DID/Base58.swift similarity index 100% rename from Sources/WalletConnectRelay/ClientAuth/Base58.swift rename to Sources/WalletConnectUtils/DID/Base58.swift diff --git a/Sources/WalletConnectRelay/ClientAuth/DIDKeyFactory.swift b/Sources/WalletConnectUtils/DID/DIDKeyFactory.swift similarity index 100% rename from Sources/WalletConnectRelay/ClientAuth/DIDKeyFactory.swift rename to Sources/WalletConnectUtils/DID/DIDKeyFactory.swift diff --git a/Sources/WalletConnectSigner/DIDPKH/DIDPKH.swift b/Sources/WalletConnectUtils/DID/DIDPKH.swift similarity index 88% rename from Sources/WalletConnectSigner/DIDPKH/DIDPKH.swift rename to Sources/WalletConnectUtils/DID/DIDPKH.swift index a625b231a..065569cc2 100644 --- a/Sources/WalletConnectSigner/DIDPKH/DIDPKH.swift +++ b/Sources/WalletConnectUtils/DID/DIDPKH.swift @@ -31,3 +31,10 @@ public struct DIDPKH { self.account = account } } + +extension Account { + + public var iss: String { + return DIDPKH(account: self).iss + } +} diff --git a/Sources/WalletConnectSigner/SIWE/SIWECacaoFormatter.swift b/Sources/WalletConnectUtils/SIWE/SIWECacaoFormatter.swift similarity index 100% rename from Sources/WalletConnectSigner/SIWE/SIWECacaoFormatter.swift rename to Sources/WalletConnectUtils/SIWE/SIWECacaoFormatter.swift diff --git a/Sources/WalletConnectSigner/SIWE/SIWEMessage.swift b/Sources/WalletConnectUtils/SIWE/SIWEMessage.swift similarity index 100% rename from Sources/WalletConnectSigner/SIWE/SIWEMessage.swift rename to Sources/WalletConnectUtils/SIWE/SIWEMessage.swift From b34abce20464d0f5c7bf39105feddefcb403a8b1 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Mon, 6 Feb 2023 18:07:26 +0530 Subject: [PATCH 10/17] Resolve methods --- .../Identity/IdentityRegisterService.swift | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift b/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift index 68353adfe..4d024d601 100644 --- a/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift +++ b/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift @@ -56,9 +56,19 @@ actor IdentityRegisterService { publicKeyString: inviteKey.publicKey.hexRepresentation )) + // TODO: Handle private mode + try identityStorage.saveIdentityKey(inviteKey, for: account) return inviteKey.publicKey.hexRepresentation } + + func resolveIdentity(publicKey: String) async throws -> Cacao { + return try await identityNetworkService.resolveIdentity(publicKey: publicKey) + } + + func resolveInvite(account: Account) async throws -> String { + return try await identityNetworkService.resolveInvite(account: account.absoluteString) + } } private extension IdentityRegisterService { From 6471c26d95343a6063ed8a092ec1d0c9c7a37684 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Mon, 6 Feb 2023 20:51:30 +0530 Subject: [PATCH 11/17] Registry integration tests --- .../IntegrationTests/Chat/RegistryTests.swift | 45 +++++++++++++++++++ ...yKeyService.swift => IdentityKeyAPI.swift} | 15 ++++++- .../Identity/IdentityNetworkService.swift | 7 ++- .../Identity/IdentityRegisterService.swift | 17 +++---- .../Signer/MessageSigner.swift | 12 +++++ 5 files changed, 82 insertions(+), 14 deletions(-) rename Sources/Chat/ProtocolServices/Identity/{IdentityKeyService.swift => IdentityKeyAPI.swift} (80%) diff --git a/Example/IntegrationTests/Chat/RegistryTests.swift b/Example/IntegrationTests/Chat/RegistryTests.swift index ea21c9375..2ce757b80 100644 --- a/Example/IntegrationTests/Chat/RegistryTests.swift +++ b/Example/IntegrationTests/Chat/RegistryTests.swift @@ -6,4 +6,49 @@ import WalletConnectUtils final class RegistryTests: XCTestCase { + let account = Account("eip155:1:0x15bca56b6e2728aec2532df9d436bd1600e86688")! + let privateKey = Data(hex: "305c6cde3846927892cd32762f6120539f3ec74c9e3a16b9b798b1e85351ae2a") + + var sut: IdentityRegisterService! + var storage: IdentityStorage! + var signer: CacaoMessageSigner! + + override func setUp() { + let keyserverURL = URL(string: "https://staging.keys.walletconnect.com")! + let httpService = HTTPNetworkClient(host: keyserverURL.host!) + let accountService = AccountService(currentAccount: account) + let identityNetworkService = IdentityNetworkService(accountService: accountService, httpService: httpService) + storage = IdentityStorage(keychain: KeychainStorageMock()) + sut = IdentityRegisterService( + keyserverURL: keyserverURL, + identityStorage: storage, + identityNetworkService: identityNetworkService, + iatProvader: DefaultIATProvider(), + messageFormatter: SIWECacaoFormatter() + ) + signer = MessageSignerFactory(signerFactory: DefaultSignerFactory()).create(projectId: InputConfig.projectId) + } + + func testRegisterIdentity() async throws { + var message: String! + let publicKey = try await sut.registerIdentity(account: account, isPrivate: false) { msg in + message = msg + return try! signer.sign(message: msg, privateKey: privateKey, type: .eip191) + } + + let cacao = try await sut.resolveIdentity(publicKey: publicKey) + let recovered = storage.getIdentityKey(for: account)!.publicKey.hexRepresentation + + XCTAssertEqual(try SIWECacaoFormatter().formatMessage(from: cacao.p), message) + XCTAssertEqual(publicKey, recovered) + } + + func testRegisterInviteKey() async throws { + let inviteKey = try await sut.registerInvite(account: account, isPrivate: false, onSign: { msg in + return try! signer.sign(message: msg, privateKey: privateKey, type: .eip191) + }) + + let recovered = storage.getInviteKey(for: account)! + XCTAssertEqual(inviteKey, recovered.publicKey.hexRepresentation) + } } diff --git a/Sources/Chat/ProtocolServices/Identity/IdentityKeyService.swift b/Sources/Chat/ProtocolServices/Identity/IdentityKeyAPI.swift similarity index 80% rename from Sources/Chat/ProtocolServices/Identity/IdentityKeyService.swift rename to Sources/Chat/ProtocolServices/Identity/IdentityKeyAPI.swift index 131a143df..1346d40ac 100644 --- a/Sources/Chat/ProtocolServices/Identity/IdentityKeyService.swift +++ b/Sources/Chat/ProtocolServices/Identity/IdentityKeyAPI.swift @@ -32,9 +32,9 @@ enum IdentityKeyAPI: HTTPService { var body: Data? { switch self { case .registerIdentity(let cacao), .removeIdentity(let cacao): - return try? JSONEncoder().encode(cacao) + return try? JSONEncoder().encode(RegisterIdentityRequest(cacao: cacao)) case .registerInvite(let idAuth), .removeInvite(let idAuth): - return try? JSONEncoder().encode(["idAuth": idAuth]) + return try? JSONEncoder().encode(RegisterInviteRequest(idAuth: idAuth)) case .resolveIdentity, .resolveInvite: return nil } @@ -51,3 +51,14 @@ enum IdentityKeyAPI: HTTPService { } } } + +private extension IdentityKeyAPI { + + struct RegisterIdentityRequest: Codable { + let cacao: Cacao + } + + struct RegisterInviteRequest: Codable { + let idAuth: String + } +} diff --git a/Sources/Chat/ProtocolServices/Identity/IdentityNetworkService.swift b/Sources/Chat/ProtocolServices/Identity/IdentityNetworkService.swift index 51e77b1e2..8e1d08df2 100644 --- a/Sources/Chat/ProtocolServices/Identity/IdentityNetworkService.swift +++ b/Sources/Chat/ProtocolServices/Identity/IdentityNetworkService.swift @@ -20,7 +20,7 @@ actor IdentityNetworkService { func resolveIdentity(publicKey: String) async throws -> Cacao { let api = IdentityKeyAPI.resolveIdentity(publicKey: publicKey) let response = try await httpService.request(ResolveIdentityResponse.self, at: api) - return response.cacao + return response.value.cacao } func removeIdentity(cacao: Cacao) async throws { @@ -50,7 +50,10 @@ actor IdentityNetworkService { private extension IdentityNetworkService { struct ResolveIdentityResponse: Codable { - let cacao: Cacao + struct Value: Codable { + let cacao: Cacao + } + let value: Value } struct ResolveInviteResponse: Codable { diff --git a/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift b/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift index 4d024d601..ab7ad3145 100644 --- a/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift +++ b/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift @@ -51,19 +51,19 @@ actor IdentityRegisterService { } let inviteKey = IdentityKey() - try await identityNetworkService.registerInvite(idAuth: makeIDAuth( - account: account, - publicKeyString: inviteKey.publicKey.hexRepresentation - )) + let idAuth = try makeIDAuth(account: account, inviteKey: inviteKey) + try await identityNetworkService.registerInvite(idAuth: idAuth) // TODO: Handle private mode - try identityStorage.saveIdentityKey(inviteKey, for: account) + try identityStorage.saveInviteKey(inviteKey, for: account) return inviteKey.publicKey.hexRepresentation } func resolveIdentity(publicKey: String) async throws -> Cacao { - return try await identityNetworkService.resolveIdentity(publicKey: publicKey) + let data = Data(hex: publicKey) + let did = ED25519DIDKeyFactory().make(pubKey: data, prefix: false) + return try await identityNetworkService.resolveIdentity(publicKey: did) } func resolveInvite(account: Account) async throws -> String { @@ -97,10 +97,7 @@ private extension IdentityRegisterService { return Cacao(h: cacaoHeader, p: cacaoPayload, s: cacaoSignature) } - func makeIDAuth(account: Account, publicKeyString: String) throws -> String { - guard let inviteKey = identityStorage.getInviteKey(for: account) - else { throw Errors.identityKeyNotFound } - + func makeIDAuth(account: Account, inviteKey: IdentityKey) throws -> String { return try JWTFactory().createAndSignJWT( keyPair: inviteKey, aud: getAudience(), diff --git a/Sources/WalletConnectSigner/Signer/MessageSigner.swift b/Sources/WalletConnectSigner/Signer/MessageSigner.swift index 5ecfdf8fa..b4eccf811 100644 --- a/Sources/WalletConnectSigner/Signer/MessageSigner.swift +++ b/Sources/WalletConnectSigner/Signer/MessageSigner.swift @@ -9,6 +9,11 @@ public protocol MessageSignatureVerifying { } public protocol MessageSigning { + func sign(message: String, + privateKey: Data, + type: CacaoSignatureType + ) throws -> CacaoSignature + func sign(payload: CacaoPayload, privateKey: Data, type: CacaoSignatureType @@ -41,6 +46,13 @@ struct MessageSigner: CacaoMessageSigner { ) throws -> CacaoSignature { let message = try messageFormatter.formatMessage(from: payload) + return try sign(message: message, privateKey: privateKey, type: type) + } + + func sign(message: String, + privateKey: Data, + type: CacaoSignatureType + ) throws -> CacaoSignature { guard let messageData = message.data(using: .utf8)else { throw Errors.utf8EncodingFailed From 81fa5e954d997d33edb978a78a11994ef5b70502 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Mon, 6 Feb 2023 21:19:02 +0530 Subject: [PATCH 12/17] Resolve tests --- Example/IntegrationTests/Chat/RegistryTests.swift | 15 ++++++++------- .../Identity/IdentityNetworkService.swift | 7 +++++-- .../Identity/IdentityRegisterService.swift | 10 +++++++--- Sources/WalletConnectJWT/JWTFactory.swift | 9 +-------- .../ClientAuth/SocketAuthenticator.swift | 5 +++++ 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/Example/IntegrationTests/Chat/RegistryTests.swift b/Example/IntegrationTests/Chat/RegistryTests.swift index 2ce757b80..e2f58588c 100644 --- a/Example/IntegrationTests/Chat/RegistryTests.swift +++ b/Example/IntegrationTests/Chat/RegistryTests.swift @@ -29,7 +29,7 @@ final class RegistryTests: XCTestCase { signer = MessageSignerFactory(signerFactory: DefaultSignerFactory()).create(projectId: InputConfig.projectId) } - func testRegisterIdentity() async throws { + func testRegisterIdentityAndInviteKey() async throws { var message: String! let publicKey = try await sut.registerIdentity(account: account, isPrivate: false) { msg in message = msg @@ -37,18 +37,19 @@ final class RegistryTests: XCTestCase { } let cacao = try await sut.resolveIdentity(publicKey: publicKey) - let recovered = storage.getIdentityKey(for: account)!.publicKey.hexRepresentation - XCTAssertEqual(try SIWECacaoFormatter().formatMessage(from: cacao.p), message) + + let recovered = storage.getIdentityKey(for: account)!.publicKey.hexRepresentation XCTAssertEqual(publicKey, recovered) - } - func testRegisterInviteKey() async throws { let inviteKey = try await sut.registerInvite(account: account, isPrivate: false, onSign: { msg in return try! signer.sign(message: msg, privateKey: privateKey, type: .eip191) }) - let recovered = storage.getInviteKey(for: account)! - XCTAssertEqual(inviteKey, recovered.publicKey.hexRepresentation) + let recoveredKey = storage.getInviteKey(for: account)! + XCTAssertEqual(inviteKey, recoveredKey.publicKey.hexRepresentation) + + let resolvedKey = try await sut.resolveInvite(account: account) + XCTAssertEqual(inviteKey, resolvedKey) } } diff --git a/Sources/Chat/ProtocolServices/Identity/IdentityNetworkService.swift b/Sources/Chat/ProtocolServices/Identity/IdentityNetworkService.swift index 8e1d08df2..ca460fe7e 100644 --- a/Sources/Chat/ProtocolServices/Identity/IdentityNetworkService.swift +++ b/Sources/Chat/ProtocolServices/Identity/IdentityNetworkService.swift @@ -38,7 +38,7 @@ actor IdentityNetworkService { func resolveInvite(account: String) async throws -> String { let api = IdentityKeyAPI.resolveInvite(account: account) let response = try await httpService.request(ResolveInviteResponse.self, at: api) - return response.inviteKey + return response.value.inviteKey } func removeInvite(idAuth: String) async throws { @@ -57,6 +57,9 @@ private extension IdentityNetworkService { } struct ResolveInviteResponse: Codable { - let inviteKey: String + struct Value: Codable { + let inviteKey: String + } + let value: Value } } diff --git a/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift b/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift index ab7ad3145..963290a9e 100644 --- a/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift +++ b/Sources/Chat/ProtocolServices/Identity/IdentityRegisterService.swift @@ -51,7 +51,8 @@ actor IdentityRegisterService { } let inviteKey = IdentityKey() - let idAuth = try makeIDAuth(account: account, inviteKey: inviteKey) + let invitePublicKey = inviteKey.publicKey.hexRepresentation + let idAuth = try makeIDAuth(account: account, invitePublicKey: invitePublicKey) try await identityNetworkService.registerInvite(idAuth: idAuth) // TODO: Handle private mode @@ -97,9 +98,12 @@ private extension IdentityRegisterService { return Cacao(h: cacaoHeader, p: cacaoPayload, s: cacaoSignature) } - func makeIDAuth(account: Account, inviteKey: IdentityKey) throws -> String { + func makeIDAuth(account: Account, invitePublicKey: String) throws -> String { + guard let identityKey = identityStorage.getIdentityKey(for: account) + else { throw Errors.identityKeyNotFound } return try JWTFactory().createAndSignJWT( - keyPair: inviteKey, + keyPair: identityKey, + sub: invitePublicKey, aud: getAudience(), exp: getExpiry(), pkh: account.iss diff --git a/Sources/WalletConnectJWT/JWTFactory.swift b/Sources/WalletConnectJWT/JWTFactory.swift index 17a04e124..3b459561a 100644 --- a/Sources/WalletConnectJWT/JWTFactory.swift +++ b/Sources/WalletConnectJWT/JWTFactory.swift @@ -6,23 +6,16 @@ public struct JWTFactory { public func createAndSignJWT( keyPair: SigningPrivateKey, + sub: String, aud: String, exp: Int, pkh: String? ) throws -> String { let now = Int(Date().timeIntervalSince1970) let iss = keyPair.DIDKey - let sub = generateSubject() let claims = JWT.Claims(iss: iss, sub: sub, aud: aud, iat: now, exp: exp, pkh: pkh) var jwt = JWT(claims: claims) try jwt.sign(using: EdDSASigner(keyPair)) return try jwt.encoded() } } - -private extension JWTFactory { - - private func generateSubject() -> String { - return Data.randomBytes(count: 32).toHexString() - } -} diff --git a/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift b/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift index 1cfe42174..1fbf12bac 100644 --- a/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift +++ b/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift @@ -23,6 +23,7 @@ struct SocketAuthenticator: SocketAuthenticating { private func createAndSignJWT(keyPair: SigningPrivateKey) throws -> String { return try JWTFactory().createAndSignJWT( keyPair: keyPair, + sub: getSubject(), aud: getAudience(), exp: getExpiry(), pkh: nil @@ -40,4 +41,8 @@ struct SocketAuthenticator: SocketAuthenticating { private func getAudience() -> String { return "wss://\(relayHost)" } + + private func getSubject() -> String { + return Data.randomBytes(count: 32).toHexString() + } } From 20d4a4ff229ece1cab3dd971c6d7ebce34731bef Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Mon, 6 Feb 2023 21:27:51 +0530 Subject: [PATCH 13/17] Unused libraries removed --- Package.swift | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Package.swift b/Package.swift index 9455df255..9a457fd6e 100644 --- a/Package.swift +++ b/Package.swift @@ -43,14 +43,6 @@ let package = Package( .library( name: "Web3Inbox", targets: ["Web3Inbox"]), - // TODO: Remove library - .library( - name: "WalletConnectJWT", - targets: ["WalletConnectJWT"]), - // TODO: Remove library - .library( - name: "WalletConnectSigner", - targets: ["WalletConnectSigner"]), ], dependencies: [], targets: [ From 5af776517fb6b196b0596a795f15499655b1b648 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Mon, 6 Feb 2023 21:51:21 +0530 Subject: [PATCH 14/17] WalletConnectSigner linking removed --- Example/ExampleApp.xcodeproj/project.pbxproj | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index 0ca4e2635..2982ae6f2 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -209,7 +209,6 @@ A5E22D222840C8D300E36487 /* WalletEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E22D212840C8D300E36487 /* WalletEngine.swift */; }; A5E22D242840C8DB00E36487 /* SafariEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E22D232840C8DB00E36487 /* SafariEngine.swift */; }; A5E22D2C2840EAC300E36487 /* XCUIElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E22D2B2840EAC300E36487 /* XCUIElement.swift */; }; - A5F145D7298BCCDD0051B18A /* WalletConnectSigner in Frameworks */ = {isa = PBXBuildFile; productRef = A5F145D6298BCCDD0051B18A /* WalletConnectSigner */; }; C5133A78294125CC00A8314C /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = C5133A77294125CC00A8314C /* Web3 */; }; C53AA4362941251C008EA57C /* DefaultSignerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */; }; C55D347F295DD7140004314A /* AuthRequestModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D347A295DD7140004314A /* AuthRequestModule.swift */; }; @@ -676,7 +675,6 @@ A5C8BE85292FE20B006CC85C /* Web3 in Frameworks */, 84DDB4ED28ABB663003D66ED /* WalletConnectAuth in Frameworks */, C5DD5BE1294E09E3008FD3A4 /* Web3Wallet in Frameworks */, - A5F145D7298BCCDD0051B18A /* WalletConnectSigner in Frameworks */, A5E03E01286466EA00888481 /* WalletConnectChat in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1871,7 +1869,6 @@ 847CF3AE28E3141700F1D760 /* WalletConnectPush */, A5C8BE84292FE20B006CC85C /* Web3 */, C5DD5BE0294E09E3008FD3A4 /* Web3Wallet */, - A5F145D6298BCCDD0051B18A /* WalletConnectSigner */, ); productName = IntegrationTests; productReference = A5E03DED286464DB00888481 /* IntegrationTests.xctest */; @@ -3175,10 +3172,6 @@ isa = XCSwiftPackageProductDependency; productName = WalletConnectChat; }; - A5F145D6298BCCDD0051B18A /* WalletConnectSigner */ = { - isa = XCSwiftPackageProductDependency; - productName = WalletConnectSigner; - }; C5133A77294125CC00A8314C /* Web3 */ = { isa = XCSwiftPackageProductDependency; package = A5AE354528A1A2AC0059AE8A /* XCRemoteSwiftPackageReference "Web3" */; From e6c1defc094196d335730f0101b0753fc9267a40 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 7 Feb 2023 18:27:18 +0530 Subject: [PATCH 15/17] Unit tests build error --- Tests/Web3WalletTests/Mocks/AuthClientMock.swift | 2 +- Tests/Web3WalletTests/Web3WalletTests.swift | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Tests/Web3WalletTests/Mocks/AuthClientMock.swift b/Tests/Web3WalletTests/Mocks/AuthClientMock.swift index 3b1a3a68d..4f3e50c39 100644 --- a/Tests/Web3WalletTests/Mocks/AuthClientMock.swift +++ b/Tests/Web3WalletTests/Mocks/AuthClientMock.swift @@ -42,7 +42,7 @@ final class AuthClientMock: AuthClientProtocol { rejectCalled = true } - func getPendingRequests(account: WalletConnectUtils.Account) throws -> [AuthRequest] { + func getPendingRequests() throws -> [AuthRequest] { return [authRequest] } } diff --git a/Tests/Web3WalletTests/Web3WalletTests.swift b/Tests/Web3WalletTests/Web3WalletTests.swift index 7ce173cc5..8962e88a1 100644 --- a/Tests/Web3WalletTests/Web3WalletTests.swift +++ b/Tests/Web3WalletTests/Web3WalletTests.swift @@ -186,8 +186,7 @@ final class Web3WalletTests: XCTestCase { } func testAuthPendingRequestsCalledAndNotEmpty() async { - let account = Account("eip155:56:0xe5EeF1368781911d265fDB6946613dA61915a501")! - let pendingRequests = try! web3WalletClient.getPendingRequests(account: account) + let pendingRequests = try! web3WalletClient.getPendingRequests() XCTAssertEqual(1, pendingRequests.count) } } From 888c33174494c95277b73d32c067b3430f9faf55 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Wed, 8 Feb 2023 14:28:47 +0530 Subject: [PATCH 16/17] Unit tests fix --- Tests/RelayerTests/AuthTests/EdDSASignerTests.swift | 1 + Tests/RelayerTests/AuthTests/JWTTests.swift | 3 ++- Tests/RelayerTests/Mocks/EdDSASignerMock.swift | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Tests/RelayerTests/AuthTests/EdDSASignerTests.swift b/Tests/RelayerTests/AuthTests/EdDSASignerTests.swift index 2e5643785..913a2bed1 100644 --- a/Tests/RelayerTests/AuthTests/EdDSASignerTests.swift +++ b/Tests/RelayerTests/AuthTests/EdDSASignerTests.swift @@ -2,6 +2,7 @@ import Foundation import XCTest import WalletConnectKMS @testable import WalletConnectRelay +@testable import WalletConnectJWT final class EdDSASignerTests: XCTestCase { var sut: EdDSASigner! diff --git a/Tests/RelayerTests/AuthTests/JWTTests.swift b/Tests/RelayerTests/AuthTests/JWTTests.swift index 8f20cd961..d2eb4d8b6 100644 --- a/Tests/RelayerTests/AuthTests/JWTTests.swift +++ b/Tests/RelayerTests/AuthTests/JWTTests.swift @@ -1,6 +1,7 @@ import Foundation import XCTest @testable import WalletConnectRelay +@testable import WalletConnectJWT final class JWTTests: XCTestCase { let expectedJWT = "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NTY5MTAwOTcsImV4cCI6MTY1Njk5NjQ5NywiaXNzIjoiZGlkOmtleTp6Nk1rb2RIWnduZVZSU2h0YUxmOEpLWWt4cERHcDF2R1pucEdtZEJwWDhNMmV4eEgiLCJzdWIiOiJjNDc5ZmU1ZGM0NjRlNzcxZTc4YjE5M2QyMzlhNjViNThkMjc4Y2FkMWMzNGJmYjBiNTcxNmU1YmI1MTQ5MjhlIiwiYXVkIjoid3NzOi8vcmVsYXkud2FsbGV0Y29ubmVjdC5jb20ifQ.0JkxOM-FV21U7Hk-xycargj_qNRaYV2H5HYtE4GzAeVQYiKWj7YySY5AdSqtCgGzX4Gt98XWXn2kSr9rE1qvCA" @@ -27,6 +28,6 @@ extension JWT.Claims { let aud = "wss://relay.walletconnect.com" let expDate = Calendar.current.date(byAdding: components, to: iatDate)! let exp = Int(expDate.timeIntervalSince1970) - return JWT.Claims(iss: iss, sub: sub, aud: aud, iat: iat, exp: exp) + return JWT.Claims(iss: iss, sub: sub, aud: aud, iat: iat, exp: exp, pkh: nil) } } diff --git a/Tests/RelayerTests/Mocks/EdDSASignerMock.swift b/Tests/RelayerTests/Mocks/EdDSASignerMock.swift index b7ca50718..dc52ed565 100644 --- a/Tests/RelayerTests/Mocks/EdDSASignerMock.swift +++ b/Tests/RelayerTests/Mocks/EdDSASignerMock.swift @@ -1,4 +1,5 @@ import Foundation +@testable import WalletConnectJWT @testable import WalletConnectRelay class EdDSASignerMock: JWTSigning { From 2e17fa49878d5230d06b126c5469d5c925074ee2 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Wed, 8 Feb 2023 15:15:19 +0530 Subject: [PATCH 17/17] MessageSignerMock fixed --- Tests/AuthTests/Stubs/MessageSignerMock.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Tests/AuthTests/Stubs/MessageSignerMock.swift b/Tests/AuthTests/Stubs/MessageSignerMock.swift index 1d3cf358d..869febeeb 100644 --- a/Tests/AuthTests/Stubs/MessageSignerMock.swift +++ b/Tests/AuthTests/Stubs/MessageSignerMock.swift @@ -2,6 +2,9 @@ import Foundation import Auth struct MessageSignerMock: CacaoMessageSigner { + func sign(message: String, privateKey: Data, type: WalletConnectUtils.CacaoSignatureType) throws -> WalletConnectUtils.CacaoSignature { + return CacaoSignature(t: .eip191, s: "") + } func verify(signature: CacaoSignature, message: String,