diff --git a/Sources/TorusUtils/Helpers/Common.swift b/Sources/TorusUtils/Helpers/Common.swift index 601d1e0b..648d8d6e 100644 --- a/Sources/TorusUtils/Helpers/Common.swift +++ b/Sources/TorusUtils/Helpers/Common.swift @@ -21,23 +21,6 @@ internal func normalizeKeysResult(result: VerifierLookupResponse) -> KeyLookupRe return finalResult } -internal func normalizeLegacyKeysResult(result: LegacyVerifierLookupResponse) -> LegacyKeyLookupResult.LegacyKeyResult { - var finalResult = LegacyKeyLookupResult.LegacyKeyResult() - - if !result.keys.isEmpty { - let finalKey = result.keys[0] - finalResult.keys = [ - LegacyVerifierLookupResponse.Key( - pub_key_X: finalKey.pub_key_X, - pub_key_Y: finalKey.pub_key_Y, - address: finalKey.address - ), - ] - } - - return finalResult -} - internal func kCombinations(elements: ArraySlice, k: Int) -> [[T]] { if k == 0 || k > elements.count { return [] diff --git a/Sources/TorusUtils/Helpers/NodeUtils.swift b/Sources/TorusUtils/Helpers/NodeUtils.swift index c1c37688..0dadfb9e 100644 --- a/Sources/TorusUtils/Helpers/NodeUtils.swift +++ b/Sources/TorusUtils/Helpers/NodeUtils.swift @@ -526,135 +526,4 @@ public class NodeUtils { ) ) } - - public static func legacyKeyLookup(endpoints: [String], verifier: String, verifierId: String, timeout: TimeInterval = TimeInterval(0)) async throws -> LegacyKeyLookupResult { - let session = URLSession(configuration: .default) - if timeout != TimeInterval(0) { - session.configuration.timeoutIntervalForRequest = timeout - } - - let encoder = JSONEncoder() - encoder.outputFormatting = .sortedKeys - let params = VerifierLookupParams(verifier: verifier, verifier_id: verifierId, client_time: String(Int(floor(Double(Date().timeIntervalSince1970 / 1000))))) - let jRPCRequest = JRPCRequest( - method: JRPC_METHODS.VERIFIER_LOOKUP_REQUEST, - params: params) - let rpcdata = try encoder.encode(jRPCRequest) - - let lookupResults: [JRPCResponse?] = try await withThrowingTaskGroup(of: JRPCResponse?.self, returning: [JRPCResponse?].self) { group -> [JRPCResponse?] in - for endpoint in endpoints { - group.addTask { - do { - var request = try MetadataUtils.makeUrlRequest(url: endpoint) - request.httpBody = rpcdata - let val = try await URLSession(configuration: .default).data(for: request) - let decoded = try JSONDecoder().decode(JRPCResponse.self, from: val.0) - return decoded - } catch { - return nil - } - } - } - var collected = [JRPCResponse?]() - for try await value in group { - collected.append(value) - } - return collected - } - - let lookupShares = lookupResults.filter({ $0 != nil }) - - let threshold = Int(trunc(Double(endpoints.count / 2) + 1)) - - let errorResult = try thresholdSame(arr: lookupShares.map({ $0?.error }), threshold: threshold) - - let keyResults = lookupResults.filter({ $0 != nil && $0?.result != nil }).map { normalizeLegacyKeysResult(result: ($0!.result)!) } - - let keyResult = try thresholdSame(arr: keyResults, threshold: threshold) - - var serverTimeOffsets: [Int] = [] - - if keyResult != nil { - for item in keyResults { - let timeOffset = item.server_time_offset - serverTimeOffsets.append(Int(timeOffset ?? "0")!) - } - } - - if keyResult == nil && errorResult == nil { - throw TorusUtilError.apiRequestFailed - } - - let serverTimeOffset = keyResult != nil ? calculateMedian(arr: serverTimeOffsets) : 0 - - return LegacyKeyLookupResult(keyResult: keyResult, errorResult: errorResult as? ErrorMessage, serverTimeOffset: serverTimeOffset) - } - - public static func legacyKeyAssign(keyAssignInput: KeyAssignInput, apiKey: String) async throws { - var nodeNum: Int = 0 - var initialPoint: Int? - if keyAssignInput.lastPoint == nil { - nodeNum = Int(floor(Double(Int.random(in: 0 ..< 1) * keyAssignInput.endpoints.count))) - initialPoint = nodeNum - } else { - nodeNum = (keyAssignInput.lastPoint ?? 0) / keyAssignInput.endpoints.count - } - - // This check looked like it should appear before the next check - // since the next check could have compared zero to nil - if keyAssignInput.firstPoint != nil { - initialPoint = keyAssignInput.firstPoint! - } - - if nodeNum == initialPoint { - throw TorusUtilError.apiRequestFailed - } - - let params = SignerParams(verifier: keyAssignInput.verifier, varifier_id: keyAssignInput.verifierId) - let encoder = JSONEncoder() - encoder.outputFormatting = .sortedKeys - - let session = URLSession(configuration: .default) - var request = try MetadataUtils.makeUrlRequest(url: keyAssignInput.signerHost) - request.addValue(apiKey, forHTTPHeaderField: "x-api-key") - request.addValue(keyAssignInput.torusNodePubs[nodeNum].X, forHTTPHeaderField: "pubkeyx") - request.addValue(keyAssignInput.torusNodePubs[nodeNum].Y, forHTTPHeaderField: "pubkeyy") - request.addValue(keyAssignInput.network.name, forHTTPHeaderField: "network") - request.addValue(keyAssignInput.clientId, forHTTPHeaderField: "clientId") - let data = try encoder.encode(params) - request.httpBody = data - - let response: (Data, URLResponse) = try await session.data(for: request) - let signerResponse = try JSONDecoder().decode(SignerResponse.self, from: response.0) - - let keyAssignRequestParams = KeyAssignRequestParams(params: params, signerResponse: signerResponse) - let newData = try encoder.encode(keyAssignRequestParams) - - var request2 = try MetadataUtils.makeUrlRequest(url: keyAssignInput.endpoints[nodeNum]) - request2.httpBody = newData - - let keyAssignRequestData: (Data, URLResponse) = try await session.data(for: request2) - - let decodedData = try JSONDecoder().decode(JRPCResponse.self, from: keyAssignRequestData.0) - - if decodedData.error != nil && ( - [502, 504, 401].contains(decodedData.error!.code) || - ["Timed out", - "Failed to fetch", - "cancelled", - "NetworkError when attempting to fetch resource.", - "TypeError: Failed to fetch", - "TypeError: cancelled", - "TypeError: NetworkError when attempting to fetch resource.", - "reason: getaddrinfo EAI_AGAIN"].contains(decodedData.error!.message) - ) { - var retry = keyAssignInput - retry.lastPoint = nodeNum + 1 - try await legacyKeyAssign(keyAssignInput: retry, apiKey: apiKey) - } - } - - public static func legacyWaitKeyLookup(endpoints: [String], verifier: String, verifierId: String, timeout: TimeInterval) async throws -> LegacyKeyLookupResult { - try await legacyKeyLookup(endpoints: endpoints, verifier: verifier, verifierId: verifierId, timeout: timeout) - } } diff --git a/Sources/TorusUtils/Helpers/jsonRPC/Responses/ShareResponse/KeyAssignment/LegacyKeyAssignment.swift b/Sources/TorusUtils/Helpers/jsonRPC/Responses/ShareResponse/KeyAssignment/LegacyKeyAssignment.swift deleted file mode 100644 index 875519b9..00000000 --- a/Sources/TorusUtils/Helpers/jsonRPC/Responses/ShareResponse/KeyAssignment/LegacyKeyAssignment.swift +++ /dev/null @@ -1,15 +0,0 @@ -import Foundation - -public struct LegacyKeyAssignment: Codable { - let index: String - let publicKey: PublicKey - let threshold: String - let verifiers: [String: [String]] - let share: String - let metadata: EciesHex? - - struct PublicKey: Hashable, Codable { - let X: String - let Y: String - } -} diff --git a/Sources/TorusUtils/Helpers/jsonRPC/Responses/ShareResponse/LegacyShareRequestResult.swift b/Sources/TorusUtils/Helpers/jsonRPC/Responses/ShareResponse/LegacyShareRequestResult.swift deleted file mode 100644 index cd27c6d9..00000000 --- a/Sources/TorusUtils/Helpers/jsonRPC/Responses/ShareResponse/LegacyShareRequestResult.swift +++ /dev/null @@ -1,28 +0,0 @@ -import Foundation - -struct LegacyShareRequestResult: Codable { - let keys: [LegacyKeyAssignment] - let serverTimeOffset: String - - enum CodingKeys: CodingKey { - case keys - case server_time_offset - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(keys, forKey: .keys) - try container.encode(serverTimeOffset, forKey: .server_time_offset) - } - - init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - keys = try container.decode([LegacyKeyAssignment].self, forKey: .keys) - - if let serverTimeOffset = try? container.decodeIfPresent(String.self, forKey: .server_time_offset) { - self.serverTimeOffset = serverTimeOffset - } else { - serverTimeOffset = "0" - } - } -} diff --git a/Sources/TorusUtils/Interfaces/KeyLookup/LegacyKeyLookupResult.swift b/Sources/TorusUtils/Interfaces/KeyLookup/LegacyKeyLookupResult.swift deleted file mode 100644 index 499c0a6c..00000000 --- a/Sources/TorusUtils/Interfaces/KeyLookup/LegacyKeyLookupResult.swift +++ /dev/null @@ -1,28 +0,0 @@ -import Foundation - -public struct LegacyKeyLookupResult { - public struct LegacyKeyResult: Codable { - public var keys: [LegacyVerifierLookupResponse.Key] - public let server_time_offset: String? - - public init(keys: [LegacyVerifierLookupResponse.Key], server_time_offset: String?) { - self.keys = keys - self.server_time_offset = server_time_offset - } - - public init() { - keys = [] - server_time_offset = nil - } - } - - public let keyResult: LegacyKeyResult? - public let errorResult: ErrorMessage? - public let serverTimeOffset: Int - - public init(keyResult: LegacyKeyResult?, errorResult: ErrorMessage?, serverTimeOffset: Int) { - self.keyResult = keyResult - self.errorResult = errorResult - self.serverTimeOffset = serverTimeOffset - } -} diff --git a/Sources/TorusUtils/TorusUtils.swift b/Sources/TorusUtils/TorusUtils.swift index 534cd662..2a096076 100644 --- a/Sources/TorusUtils/TorusUtils.swift +++ b/Sources/TorusUtils/TorusUtils.swift @@ -53,16 +53,6 @@ public class TorusUtils { signerHost = params.network.signerMap + "/api/sign" } - public func isLegacyNetwork() -> Bool { - if case let .legacy(legacyNetwork) = network { - let legacyRoute = legacyNetwork.migration_map - if !legacyRoute.migrationCompleted { - return true - } - } - return false - } - internal static func isLegacyNetworkRouteMap(network: TorusNetwork) -> Bool { if case .legacy = network { return true @@ -102,22 +92,13 @@ public class TorusUtils { // Moving this in javascript library will allow it to be done directly in the function var params: [String: Codable] = [:] params.updateValue(sessionTime, forKey: "session_token_exp_second") - - if isLegacyNetwork() { - return try await legacyRetrieveShares(endpoints: endpoints, indexes: indexes, verifier: verifier, verifierParams: verifierParams, idToken: idToken, extraParams: params) - } - + return try await NodeUtils.retrieveOrImportShare(legacyMetadataHost: legacyMetadataHost, serverTimeOffset: serverTimeOffset, enableOneKey: enableOneKey, allowHost: allowHost, network: network, clientId: clientId, endpoints: endpoints, verifier: verifier, verifierParams: verifierParams, idToken: idToken, importedShares: [], apiKey: apiKey, extraParams: params) } public func getPublicAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, extendedVerifierId: String? = nil) async throws -> TorusPublicKey { let nodePubs = TorusNodePubModelToINodePub(nodes: torusNodePubs) - if isLegacyNetwork() { - return try await getLegacyPublicAddress(endpoints: endpoints, torusNodePubs: nodePubs, verifier: verifier, verifierId: verifierId, enableOneKey: enableOneKey) - - } else { - return try await getNewPublicAddress(endpoints: endpoints, verifier: verifier, verifierId: verifierId, extendedVerifierId: extendedVerifierId, enableOneKey: enableOneKey) - } + return try await getNewPublicAddress(endpoints: endpoints, verifier: verifier, verifierId: verifierId, extendedVerifierId: extendedVerifierId, enableOneKey: enableOneKey) } public func importPrivateKey( @@ -130,10 +111,6 @@ public class TorusUtils { newPrivateKey: String ) async throws -> TorusKey { let nodePubs = TorusNodePubModelToINodePub(nodes: nodePubKeys) - - if isLegacyNetwork() { - throw TorusUtilError.runtime("This function is not supported on legacy networks") - } if endpoints.count != nodeIndexes.count { throw TorusUtilError.runtime("Length of endpoints must be the same as length of nodeIndexes") @@ -205,324 +182,9 @@ public class TorusUtils { extendedVerifierId: String? = nil ) async throws -> TorusPublicKey { let nodePubs = TorusNodePubModelToINodePub(nodes: torusNodePubs) - if isLegacyNetwork() { - return try await getLegacyPublicAddress(endpoints: endpoints, torusNodePubs: nodePubs, verifier: verifier, verifierId: verifierId, enableOneKey: true) - - } return try await getNewPublicAddress(endpoints: endpoints, verifier: verifier, verifierId: verifierId, extendedVerifierId: extendedVerifierId, enableOneKey: true) } - private func legacyRetrieveShares(endpoints: [String], - indexes: [BigUInt], - verifier: String, - verifierParams: VerifierParams, - idToken: String, - extraParams: [String: Codable]) async throws -> TorusKey { - // These common blocks http request methods should be wrapped up into common functions - // and possibly split out into a seperate library - let encoder = JSONEncoder() - encoder.outputFormatting = .sortedKeys - - let session = URLSession(configuration: .default) - var request = try MetadataUtils.makeUrlRequest(url: signerHost, httpMethod: .get) - request.addValue(apiKey, forHTTPHeaderField: "x-api-key") - request.addValue(verifier, forHTTPHeaderField: "verifier") - request.addValue(verifier, forHTTPHeaderField: "origin") - request.addValue(verifierParams.verifier_id, forHTTPHeaderField: "verifier_id") - request.addValue(network.name, forHTTPHeaderField: "network") - request.addValue(clientId, forHTTPHeaderField: "clientid") - request.addValue("true", forHTTPHeaderField: "enablegating") - - let response: (Data, URLResponse) = try await session.data(for: request) - _ = try JSONDecoder().decode(SignerResponse.self, from: response.0) - - let tmpKey = SecretKey() - let pubKey = try tmpKey.toPublic().serialize(compressed: false) - let (pubKeyX, pubKeyY) = try KeyUtils.getPublicKeyCoords(pubKey: pubKey) - - let tokenCommitment = try KeyUtils.keccak256Data(idToken) - - // Note: timestamp is missing here in javascript - let params = CommitmentRequestParams( - messageprefix: "mug00", - tokencommitment: tokenCommitment, - temppubx: pubKeyX, - temppuby: pubKeyY, - verifieridentifier: verifier, - timestamp: String(Int(trunc(Double((serverTimeOffset ?? 0) + Int(Date().timeIntervalSince1970) / 1000))))) - - let jsonRPCRequest = JRPCRequest( - method: JRPC_METHODS.COMMITMENT_REQUEST, - params: params - ) - - let rpcdata = try encoder.encode(jsonRPCRequest) - - let commitmentRequestResults: [JRPCResponse?] = try await withThrowingTaskGroup(of: JRPCResponse?.self, returning: [JRPCResponse?].self) { group -> [JRPCResponse?] in - for endpoint in endpoints { - group.addTask { - do { - var request = try MetadataUtils.makeUrlRequest(url: endpoint) - request.httpBody = rpcdata - let val = try await URLSession(configuration: .default).data(for: request) - let decoded = try JSONDecoder().decode(JRPCResponse.self, from: val.0) - return decoded - } catch { - return nil - } - } - } - var collected = [JRPCResponse?]() - for try await value in group { - collected.append(value) - } - return collected - } - - let completedCommitmentRequests = commitmentRequestResults.filter({ $0 != nil && $0?.error == nil }) - - var nodeSigs: [CommitmentRequestResult] = [] - for item in completedCommitmentRequests.map({ $0!.result }) { - nodeSigs.append(item!) - } - - let shareRequestResults: [JRPCResponse?] = try await withThrowingTaskGroup(of: JRPCResponse?.self, returning: [JRPCResponse?].self) { - group -> [JRPCResponse?] in - for i in 0 ..< nodeSigs.count { - let sigs = nodeSigs - group.addTask { - do { - let sessionExpiry: Int? = extraParams["session_token_exp_second"] as? Int - - let shareRequestItem = ShareRequestParams.ShareRequestItem( - verifieridentifier: verifier, - verifier_id: verifierParams.verifier_id, - extended_verifier_id: verifierParams.extended_verifier_id, - idtoken: idToken, - nodeSignatures: sigs, - // extra_params: extraData - sub_verifier_ids: verifierParams.sub_verifier_ids, - session_token_exp_second: sessionExpiry, - verify_params: verifierParams.verify_params - ) - - let params = ShareRequestParams(encrypted: "yes", item: [shareRequestItem], client_time: String(Int(floor(Date().timeIntervalSince1970 / 1000)))) - - let jsonRPCRequest = JRPCRequest( - method: JRPC_METHODS.SHARE_REQUEST, - params: params - ) - - let encoder = JSONEncoder() - encoder.outputFormatting = .sortedKeys - let rpcdata = try encoder.encode(jsonRPCRequest) - - var request = try MetadataUtils.makeUrlRequest(url: endpoints[i]) - request.httpBody = rpcdata - let val = try await URLSession(configuration: .default).data(for: request) - let decoded = try JSONDecoder().decode(JRPCResponse.self, from: val.0) - return decoded - } catch { - return nil - } - } - } - var collected = [JRPCResponse?]() - for try await value in group { - collected.append(value) - } - return collected - } - - let threshold = Int(trunc(Double((endpoints.count / 2) + 1))) - - let completedShareRequests = shareRequestResults.filter({ $0 != nil && $0?.result != nil }).map({ $0!.result! }) - - let thresholdPublicKey = try thresholdSame(arr: completedShareRequests.map({ $0.keys[0].publicKey }), threshold: threshold) - - // Note: flip comparison to avoid nesting - if completedShareRequests.count < threshold { - throw TorusUtilError.invalid - } - - // Note: Duplicated code - var nodeIndexes: [Int] = [] - var serverTimeOffsets: [Int] = [] - var completedShares: [String] = [] - for (index, item) in completedShareRequests.enumerated() { - serverTimeOffsets.append(Int(item.serverTimeOffset)!) - if item.keys.count > 0 { - let firstKey = item.keys[0] - if firstKey.metadata != nil { - completedShares.append( - try MetadataUtils.decrypt( - privateKey: tmpKey.serialize().addLeading0sForLength64(), - opts: ECIES( - iv: firstKey.metadata!.iv, - ephemPublicKey: firstKey.metadata!.ephemPublicKey, - ciphertext: firstKey.share, - mac: firstKey.metadata!.mac - ) - ).hexString - ) - } else { - completedShares.append(firstKey.share) - } - } - nodeIndexes.append(index) - } - - var decryptedShares: [Int: String] = [:] - for (i, item) in completedShares.enumerated() { - decryptedShares[nodeIndexes[i]] = item - } - - let elements = Array(0.. BigInt(0)) { - let privateKeyWithNonce = (BigInt(try oAuthKey.serialize(), radix: 16)! + BigInt(metadataNonce!)).modulus(KeyUtils.getOrderOfCurve()) - finalPrivKey = privateKeyWithNonce.serialize().hexString.addLeading0sForLength64() - } - - var isUpgraded: Bool? - if typeOfUser == .v2 { - isUpgraded = metadataNonce == "0" - } - - let (finalPubKeyX, finalPubKeyY) = try KeyUtils.getPublicKeyCoords(pubKey: finalPubKey!) - - let finalEvmAddress = try KeyUtils.generateAddressFromPubKey(publicKeyX: finalPubKeyX, publicKeyY: finalPubKeyY) - - return TorusKey( - finalKeyData: TorusKey.FinalKeyData( - evmAddress: finalEvmAddress, - X: finalPubKeyX, - Y: finalPubKeyY, - privKey: finalPrivKey - ), - oAuthKeyData: TorusKey.OAuthKeyData( - evmAddress: oAuthKeyAddress, - X: oAuthKeyX, - Y: oAuthKeyY, - privKey: try oAuthKey.serialize().addLeading0sForLength64() - ), - sessionData: TorusKey.SessionData( - sessionTokenData: [], - sessionAuthKey: "" - ), - metadata: TorusPublicKey.Metadata( - pubNonce: pubKeyNonceResult, - nonce: metadataNonce, - typeOfUser: typeOfUser, - upgraded: isUpgraded, - serverTimeOffset: serverTimeOffset - ), - nodesData: TorusKey.NodesData( - nodeIndexes: [] - ) - ) - } - - private func getLegacyPublicAddress(endpoints: [String], torusNodePubs: [INodePub], verifier: String, verifierId: String, enableOneKey: Bool) async throws -> TorusPublicKey { - var isNewKey = false - var finalKeyResult: LegacyKeyLookupResult.LegacyKeyResult? - - let result = try await NodeUtils.legacyKeyLookup(endpoints: endpoints, verifier: verifier, verifierId: verifierId) - - if result.errorResult != nil { - let error = result.errorResult!.message - if error.lowercased().contains("verifier not supported") { - throw TorusUtilError.runtime("Verifier not supported. Check if you: 1. Are on the right network (Torus testnet/mainnet) 2. Have setup a verifier on dashboard.web3auth.io?") - } else if error.lowercased().contains("Verifier + VerifierID has not yet been assigned") { - let keyAssignInput = KeyAssignInput(endpoints: endpoints, torusNodePubs: torusNodePubs, verifier: verifier, verifierId: verifierId, signerHost: signerHost, network: network, clientId: clientId) - _ = try await NodeUtils.legacyKeyAssign(keyAssignInput: keyAssignInput, apiKey: apiKey) - let lookup = try await NodeUtils.legacyKeyLookup(endpoints: endpoints, verifier: verifier, verifierId: verifierId) - finalKeyResult = lookup.keyResult - isNewKey = true - } else if result.keyResult != nil { - finalKeyResult = result.keyResult - } else { - throw TorusUtilError.runtime(error) - } - } - - if finalKeyResult == nil { - throw TorusUtilError.runtime("node results do not match at final lookup") - } - - let finalServerTimeOffset = (serverTimeOffset ?? Int(finalKeyResult!.server_time_offset ?? "0"))! - - let keys = finalKeyResult!.keys.map({ LegacyVerifierLookupResponse.Key(pub_key_X: $0.pub_key_X, pub_key_Y: $0.pub_key_Y, address: $0.address) }) - - let legacyVerifierLookupResponse = LegacyVerifierLookupResponse(keys: keys, serverTimeOffset: String(finalServerTimeOffset)) - - return try await formatLegacyPublicKeyData(finalKeyResult: legacyVerifierLookupResponse, enableOneKey: enableOneKey, isNewKey: isNewKey, serverTimeOffset: finalServerTimeOffset) - } - internal func generateNonceMetadataParams(operation: String, privateKey: BigInt, nonce: BigInt?) throws -> NonceMetadataParams { let privKey = try SecretKey(hex: privateKey.magnitude.serialize().hexString.addLeading0sForLength64()) @@ -566,10 +228,10 @@ public class TorusUtils { } let pubKey = KeyUtils.getPublicKeyFromCoords(pubKeyX: keyAssignResult.keyResult!.keys[0].pub_key_X, pubKeyY: keyAssignResult.keyResult!.keys[0].pub_key_Y) - + var pubNonce: PubNonce? let nonce: BigUInt = BigUInt(keyAssignResult.nonceResult?.nonce ?? "0", radix: 16)! - + var oAuthPubKey: String? var finalPubKey: String?