diff --git a/package-lock.json b/package-lock.json index f3ccf50..e8502ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,9 @@ "version": "12.2.0", "license": "MIT", "dependencies": { - "@toruslabs/constants": "^13.2.0", + "@toruslabs/constants": "^13.4.0", "@toruslabs/eccrypto": "^4.0.0", - "@toruslabs/http-helpers": "^6.1.0", + "@toruslabs/http-helpers": "^6.1.1", "bn.js": "^5.2.1", "elliptic": "^6.5.5", "ethereum-cryptography": "^2.1.3", @@ -20,12 +20,12 @@ }, "devDependencies": { "@babel/register": "^7.23.7", - "@babel/runtime": "^7.24.0", + "@babel/runtime": "^7.24.5", "@toruslabs/config": "^2.0.2", "@toruslabs/eslint-config-typescript": "^3.2.0", - "@toruslabs/fetch-node-details": "^13.2.0", - "@toruslabs/torus-scripts": "^5.3.0", - "@types/chai": "^4.3.12", + "@toruslabs/fetch-node-details": "^13.4.0", + "@toruslabs/torus-scripts": "^5.3.1", + "@types/chai": "^4.3.16", "@types/elliptic": "^6.4.18", "@types/faker": "^5.5.3", "@types/json-stable-stringify": "^1.0.36", @@ -40,12 +40,12 @@ "husky": "^9.0.11", "jsonwebtoken": "^9.0.2", "lint-staged": "^15.2.2", - "mocha": "^10.3.0", + "mocha": "^10.4.0", "prettier": "^3.2.5", "rimraf": "^5.0.5", "sinon": "^17.0.1", "ts-node": "^10.9.2", - "typescript": "^5.4.2" + "typescript": "^5.4.5" }, "engines": { "node": ">=18.x", @@ -1789,9 +1789,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", - "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", + "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2965,9 +2965,9 @@ } }, "node_modules/@toruslabs/constants": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@toruslabs/constants/-/constants-13.2.0.tgz", - "integrity": "sha512-n3nQxzsogjs76Zq3QqB9KbHfSFhlBtW4v6Z9zlVX6Pf8QraLd4OCHQFzZgrI2cDRz0oAix6Ihrzl0S7z18/J1g==", + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@toruslabs/constants/-/constants-13.4.0.tgz", + "integrity": "sha512-CjmnMQ5Oj0bqSBGkhv7Xm3LciGJDHwe4AJ1LF6mijlP+QcCnUM5I6kVp60j7zZ/r0DT7nIEiuHHHczGpCZor0A==", "engines": { "node": ">=18.x", "npm": ">=9.x" @@ -3021,14 +3021,14 @@ } }, "node_modules/@toruslabs/fetch-node-details": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@toruslabs/fetch-node-details/-/fetch-node-details-13.2.0.tgz", - "integrity": "sha512-RhrudJUeuEnrCgYn244Si8opBIrYccRJpG0THFtHhDVeeqGutHplAqG0WehkR+oIiXC9VOlVaCkNkn2cWW8/Mw==", + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@toruslabs/fetch-node-details/-/fetch-node-details-13.4.0.tgz", + "integrity": "sha512-WTfI47Q5sldlz4nh8kNPI95PXm3hjm3IEDnYRY3rlcCrs9sVwdQItKf4D0i5s9sRmwLIpG3po+IpEcdO82CIuA==", "dev": true, "dependencies": { - "@toruslabs/constants": "^13.2.0", - "@toruslabs/fnd-base": "^13.2.0", - "@toruslabs/http-helpers": "^6.1.0", + "@toruslabs/constants": "^13.4.0", + "@toruslabs/fnd-base": "^13.4.0", + "@toruslabs/http-helpers": "^6.1.1", "loglevel": "^1.9.1" }, "engines": { @@ -3040,12 +3040,12 @@ } }, "node_modules/@toruslabs/fnd-base": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@toruslabs/fnd-base/-/fnd-base-13.2.0.tgz", - "integrity": "sha512-GPrAztgh3FNPl0BrALFHgZbnGU4pmFAEJE8xkeLxV1GGmqA4YxzQfrpkPz9RsAv+HbYIS1DHKTEvvgOjmym+5A==", + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@toruslabs/fnd-base/-/fnd-base-13.4.0.tgz", + "integrity": "sha512-Fc3uFj5ZfDmR4uWAMRyLVvBsSLXJWBHQoHOsucVqvxXpNeLSrFEQIxqlXsgjRfQPOSKtpljSl1MaXibhb5/hfA==", "dev": true, "dependencies": { - "@toruslabs/constants": "^13.2.0" + "@toruslabs/constants": "^13.4.0" }, "engines": { "node": ">=18.x", @@ -3056,9 +3056,9 @@ } }, "node_modules/@toruslabs/http-helpers": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@toruslabs/http-helpers/-/http-helpers-6.1.0.tgz", - "integrity": "sha512-tRBhlY5ccFAf3yZC5/gPXPq9LWX8ipeYyVjJO6exZjeXNxPEyz3IIsuQvxpBYLaQ72XihNdsKiYp2dEdUPEFyw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@toruslabs/http-helpers/-/http-helpers-6.1.1.tgz", + "integrity": "sha512-bJYOaltRzklzObhRdutT1wau17vXyrCCBKJOeN46F1t99MUXi5udQNeErFOcr9qBsvrq2q67eVBkU5XOeBMX5A==", "dependencies": { "lodash.merge": "^4.6.2", "loglevel": "^1.9.1" @@ -3078,9 +3078,9 @@ } }, "node_modules/@toruslabs/torus-scripts": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@toruslabs/torus-scripts/-/torus-scripts-5.3.0.tgz", - "integrity": "sha512-l4NqW8dVQYgIQZv9A4gxb/mrRkkJhsXpC+8G1hHPqmRKzh1rbEkOyjkC8MyLO+3GyOlcUEwFREE9o6eFxbsIGg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@toruslabs/torus-scripts/-/torus-scripts-5.3.1.tgz", + "integrity": "sha512-W/h+ZHxBZocxncqskm2VOa4eWpQ8J0oq2sQsMcUL5iai1+plD47r7No+0zu1lnNGYVxuQIpQug2FALeiZ2pVlw==", "dev": true, "dependencies": { "@babel/core": "^7.24.0", @@ -3183,9 +3183,9 @@ } }, "node_modules/@types/chai": { - "version": "4.3.12", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.12.tgz", - "integrity": "sha512-zNKDHG/1yxm8Il6uCCVsm+dRdEsJlFoDu73X17y09bId6UwoYww+vFBsAcRzl8knM1sab3Dp1VRikFQwDOtDDw==", + "version": "4.3.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", + "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", "dev": true }, "node_modules/@types/elliptic": { @@ -10215,9 +10215,9 @@ } }, "node_modules/mocha": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz", - "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", + "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", "dev": true, "dependencies": { "ansi-colors": "4.1.1", @@ -13277,9 +13277,9 @@ } }, "node_modules/typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 254be28..71cc538 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,9 @@ "@babel/runtime": "7.x" }, "dependencies": { - "@toruslabs/constants": "^13.2.0", + "@toruslabs/constants": "^13.4.0", "@toruslabs/eccrypto": "^4.0.0", - "@toruslabs/http-helpers": "^6.1.0", + "@toruslabs/http-helpers": "^6.1.1", "bn.js": "^5.2.1", "elliptic": "^6.5.5", "ethereum-cryptography": "^2.1.3", @@ -34,12 +34,12 @@ }, "devDependencies": { "@babel/register": "^7.23.7", - "@babel/runtime": "^7.24.0", + "@babel/runtime": "^7.24.5", "@toruslabs/config": "^2.0.2", "@toruslabs/eslint-config-typescript": "^3.2.0", - "@toruslabs/fetch-node-details": "^13.2.0", - "@toruslabs/torus-scripts": "^5.3.0", - "@types/chai": "^4.3.12", + "@toruslabs/fetch-node-details": "^13.4.0", + "@toruslabs/torus-scripts": "^5.3.1", + "@types/chai": "^4.3.16", "@types/elliptic": "^6.4.18", "@types/faker": "^5.5.3", "@types/json-stable-stringify": "^1.0.36", @@ -54,12 +54,12 @@ "husky": "^9.0.11", "jsonwebtoken": "^9.0.2", "lint-staged": "^15.2.2", - "mocha": "^10.3.0", + "mocha": "^10.4.0", "prettier": "^3.2.5", "rimraf": "^5.0.5", "sinon": "^17.0.1", "ts-node": "^10.9.2", - "typescript": "^5.4.2" + "typescript": "^5.4.5" }, "repository": { "type": "git", diff --git a/src/helpers/common.ts b/src/helpers/common.ts index 05be00b..a69a673 100644 --- a/src/helpers/common.ts +++ b/src/helpers/common.ts @@ -1,7 +1,7 @@ import { Ecies } from "@toruslabs/eccrypto"; import JsonStringify from "json-stable-stringify"; -import { EciesHex, LegacyVerifierLookupResponse, VerifierLookupResponse } from "../interfaces"; +import { EciesHex, VerifierLookupResponse } from "../interfaces"; // this function normalizes the result from nodes before passing the result to threshold check function // For ex: some fields returns by nodes might be different from each other @@ -25,26 +25,6 @@ export const normalizeKeysResult = (result: VerifierLookupResponse) => { return finalResult; }; -// this function normalizes the result from nodes before passing the result to threshold check function -// For ex: some fields returns by nodes might be different from each other -// like key_index which may differ on sapphire_network for each queried node -export const normalizeLegacyKeysResult = (result: LegacyVerifierLookupResponse) => { - const finalResult: Pick = { - keys: [], - }; - if (result && result.keys && result.keys.length > 0) { - const finalKey = result.keys[0]; - finalResult.keys = [ - { - pub_key_X: finalKey.pub_key_X, - pub_key_Y: finalKey.pub_key_Y, - address: finalKey.address, - }, - ]; - } - return finalResult; -}; - export const kCombinations = (s: number | number[], k: number): number[][] => { let set = s; if (typeof set === "number") { diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 173e8c4..0d5ce28 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -12,13 +12,9 @@ import { ImportedShare, ImportShareRequestResult, JRPCResponse, - KeyAssignInput, KeyLookupResult, - LegacyKeyLookupResult, - LegacyVerifierLookupResponse, SessionToken, ShareRequestResult, - SignerResponse, TorusKey, UserType, v2NonceResultType, @@ -27,7 +23,7 @@ import { } from "../interfaces"; import log from "../loglevel"; import { Some } from "../some"; -import { calculateMedian, kCombinations, normalizeKeysResult, normalizeLegacyKeysResult, thresholdSame } from "./common"; +import { calculateMedian, kCombinations, normalizeKeysResult, thresholdSame } from "./common"; import { generateAddressFromPrivKey, generateAddressFromPubKey, keccak256 } from "./keyUtils"; import { lagrangeInterpolation } from "./langrangeInterpolatePoly"; import { decryptNodeData, getMetadata, getOrSetNonce } from "./metadataUtils"; @@ -40,6 +36,7 @@ export const GetPubKeyOrKeyAssign = async (params: { extendedVerifierId?: string; }): Promise => { const { endpoints, network, verifier, verifierId, extendedVerifierId } = params; + const minThreshold = ~~(endpoints.length / 2) + 1; const lookupPromises = endpoints.map((x) => post>( x, @@ -69,12 +66,12 @@ export const GetPubKeyOrKeyAssign = async (params: { const errorResult = thresholdSame( lookupPubKeys.map((x2) => x2 && x2.error), - ~~(endpoints.length / 2) + 1 + minThreshold ); const keyResult = thresholdSame( lookupPubKeys.map((x3) => x3 && normalizeKeysResult(x3.result)), - ~~(endpoints.length / 2) + 1 + minThreshold ); // check for nonce result in response if not a extendedVerifierId and not a legacy network @@ -142,6 +139,7 @@ export async function retrieveOrImportShare(params: { idToken: string; importedShares?: ImportedShare[]; extraParams: Record; + indexes: number[]; }): Promise { const { legacyMetadataHost, @@ -158,6 +156,7 @@ export async function retrieveOrImportShare(params: { extraParams, serverTimeOffset, } = params; + const minThreshold = ~~(endpoints.length / 2) + 1; await get( allowHost, { @@ -227,9 +226,9 @@ export async function retrieveOrImportShare(params: { }); // we need to get commitments from all endpoints for importing share - if (importedShares.length > 0 && completedRequests.length === endpoints.length) { + if (importedShares?.length > 0 && completedRequests.length === endpoints.length) { return Promise.resolve(resultArr); - } else if (importedShares.length === 0 && completedRequests.length >= ~~((endpoints.length * 3) / 4) + 1) { + } else if (importedShares?.length === 0 && completedRequests.length >= ~~((endpoints.length * 3) / 4) + 1) { const requiredNodeResult = completedRequests.find((resp: void | JRPCResponse) => { if (resp && resp.result?.nodeindex === "1") { return true; @@ -352,7 +351,7 @@ export async function retrieveOrImportShare(params: { return undefined; }); - const thresholdPublicKey = thresholdSame(pubkeys, ~~(endpoints.length / 2) + 1); + const thresholdPublicKey = thresholdSame(pubkeys, minThreshold); if (!thresholdPublicKey) { throw new Error("invalid result from nodes, threshold number of public key results are not matching"); @@ -377,7 +376,7 @@ export async function retrieveOrImportShare(params: { ); } - const thresholdReqCount = importedShares.length > 0 ? endpoints.length : ~~(endpoints.length / 2) + 1; + const thresholdReqCount = importedShares.length > 0 ? endpoints.length : minThreshold; // optimistically run lagrange interpolation once threshold number of shares have been received // this is matched against the user public key to ensure that shares are consistent // Note: no need of thresholdMetadataNonce for extended_verifier_id key @@ -468,9 +467,8 @@ export async function retrieveOrImportShare(params: { return false; }); - const minThresholdRequired = ~~(endpoints.length / 2) + 1; - if (!verifierParams.extended_verifier_id && validSigs.length < minThresholdRequired) { - throw new Error(`Insufficient number of signatures from nodes, required: ${minThresholdRequired}, found: ${validSigs.length}`); + if (!verifierParams.extended_verifier_id && validSigs.length < minThreshold) { + throw new Error(`Insufficient number of signatures from nodes, required: ${minThreshold}, found: ${validSigs.length}`); } const validTokens = sessionTokensResolved.filter((token) => { @@ -480,8 +478,8 @@ export async function retrieveOrImportShare(params: { return false; }); - if (!verifierParams.extended_verifier_id && validTokens.length < minThresholdRequired) { - throw new Error(`Insufficient number of session tokens from nodes, required: ${minThresholdRequired}, found: ${validTokens.length}`); + if (!verifierParams.extended_verifier_id && validTokens.length < minThreshold) { + throw new Error(`Insufficient number of session tokens from nodes, required: ${minThreshold}, found: ${validTokens.length}`); } sessionTokensResolved.forEach((x, index) => { if (!x) sessionTokenData.push(undefined); @@ -504,7 +502,7 @@ export async function retrieveOrImportShare(params: { [] as { index: BN; value: BN }[] ); // run lagrange interpolation on all subsets, faster in the optimistic scenario than berlekamp-welch due to early exit - const allCombis = kCombinations(decryptedShares.length, ~~(endpoints.length / 2) + 1); + const allCombis = kCombinations(decryptedShares.length, minThreshold); let privateKey: BN | null = null; for (let j = 0; j < allCombis.length; j += 1) { @@ -529,7 +527,7 @@ export async function retrieveOrImportShare(params: { if (privateKey === undefined || privateKey === null) { throw new Error("could not derive private key"); } - const thresholdIsNewKey = thresholdSame(isNewKeyResponses, ~~(endpoints.length / 2) + 1); + const thresholdIsNewKey = thresholdSame(isNewKeyResponses, minThreshold); // Convert each string timestamp to a number const serverOffsetTimes = serverTimeOffsetResponses.map((timestamp) => Number.parseInt(timestamp, 10)); @@ -657,143 +655,3 @@ export async function retrieveOrImportShare(params: { } as TorusKey; }); } - -export const legacyKeyLookup = async (endpoints: string[], verifier: string, verifierId: string): Promise => { - const lookupPromises = endpoints.map((x) => - post>( - x, - generateJsonRPCObject("VerifierLookupRequest", { - verifier, - verifier_id: verifierId.toString(), - client_time: Math.floor(Date.now() / 1000).toString(), - }) - ).catch((err) => log.error("lookup request failed", err)) - ); - return Some, LegacyKeyLookupResult>(lookupPromises, (lookupResults) => { - const lookupShares = lookupResults.filter((x1) => x1); - const errorResult = thresholdSame( - lookupShares.map((x2) => x2 && x2.error), - ~~(endpoints.length / 2) + 1 - ); - const keyResult = thresholdSame( - lookupShares.map((x3) => x3 && normalizeLegacyKeysResult(x3.result)), - ~~(endpoints.length / 2) + 1 - ); - - const serverTimeOffsets: number[] = []; - // nonceResult must exist except for extendedVerifierId and legacy networks along with keyResult - if (keyResult) { - lookupResults.forEach((x1) => { - if (x1 && x1.result) { - const timeOffSet = x1.result.server_time_offset; - const serverTimeOffset = timeOffSet ? Number.parseInt(timeOffSet, 10) : 0; - serverTimeOffsets.push(serverTimeOffset); - } - }); - } - - if (keyResult || errorResult) { - const serverTimeOffset = keyResult ? calculateMedian(serverTimeOffsets) : 0; - return Promise.resolve({ keyResult, errorResult, serverTimeOffset }); - } - return Promise.reject(new Error(`invalid results ${JSON.stringify(lookupResults)}`)); - }); -}; - -export const legacyKeyAssign = async ({ - endpoints, - torusNodePubs, - lastPoint, - firstPoint, - verifier, - verifierId, - signerHost, - network, - clientId, -}: KeyAssignInput): Promise => { - let nodeNum: number; - let initialPoint: number | undefined; - if (lastPoint === undefined) { - nodeNum = Math.floor(Math.random() * endpoints.length); - // nodeNum = endpoints.indexOf("https://torus-node.binancex.dev/jrpc"); - initialPoint = nodeNum; - } else { - nodeNum = lastPoint % endpoints.length; - } - if (nodeNum === firstPoint) throw new Error("Looped through all"); - if (firstPoint !== undefined) initialPoint = firstPoint; - - const data = generateJsonRPCObject("KeyAssign", { - verifier, - verifier_id: verifierId.toString(), - }); - try { - const signedData = await post( - signerHost, - data, - { - headers: { - pubkeyx: torusNodePubs[nodeNum].X, - pubkeyy: torusNodePubs[nodeNum].Y, - network, - clientid: clientId, - }, - }, - { useAPIKey: true } - ); - return await post( - endpoints[nodeNum], - { ...data, ...signedData }, - { - headers: { - "Content-Type": "application/json; charset=utf-8", - }, - } - ); - } catch (error2: unknown) { - const error = error2 as { status: number; message: string }; - log.error(error.status, error.message, error, "key assign error"); - const acceptedErrorMsgs = [ - // Slow node - "Timed out", - "Failed to fetch", - "cancelled", - "NetworkError when attempting to fetch resource.", - // Happens when the node is not reachable (dns issue etc) - "TypeError: Failed to fetch", // All except iOS and Firefox - "TypeError: cancelled", // iOS - "TypeError: NetworkError when attempting to fetch resource.", // Firefox - ]; - if ( - error?.status === 502 || - error?.status === 504 || - error?.status === 401 || - acceptedErrorMsgs.includes(error.message) || - acceptedErrorMsgs.some((x) => error.message?.includes(x)) || - (error.message && error.message.includes("reason: getaddrinfo EAI_AGAIN")) - ) - return legacyKeyAssign({ - endpoints, - torusNodePubs, - lastPoint: nodeNum + 1, - firstPoint: initialPoint, - verifier, - verifierId, - signerHost, - network, - clientId, - }); - throw new Error( - `Sorry, the Torus Network that powers Web3Auth is currently very busy. - We will generate your key in time. Pls try again later. \n - ${error.message || ""}` - ); - } -}; - -export const legacyWaitKeyLookup = (endpoints: string[], verifier: string, verifierId: string, timeout: number): Promise => - new Promise((resolve, reject) => { - setTimeout(() => { - legacyKeyLookup(endpoints, verifier, verifierId).then(resolve).catch(reject); - }, timeout); - }); diff --git a/src/interfaces.ts b/src/interfaces.ts index 891b1fa..d291acd 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -1,4 +1,4 @@ -import type { INodePub, TORUS_NETWORK_TYPE } from "@toruslabs/constants"; +import type { TORUS_NETWORK_TYPE } from "@toruslabs/constants"; import { Ecies } from "@toruslabs/eccrypto"; import BN from "bn.js"; @@ -74,12 +74,6 @@ export interface JRPCResponse { }; } -export interface LegacyKeyLookupResult { - keyResult: Pick; - errorResult: JRPCResponse["error"]; - serverTimeOffset: number; -} - export interface KeyLookupResult { keyResult: Pick; nodeIndexes: number[]; @@ -88,40 +82,10 @@ export interface KeyLookupResult { nonceResult?: GetOrSetNonceResult; } -export interface SignerResponse { - "torus-timestamp": string; - "torus-nonce": string; - "torus-signature": string; -} -export interface KeyAssignInput { - endpoints: string[]; - torusNodePubs: INodePub[]; - lastPoint?: number; - firstPoint?: number; - verifier: string; - verifierId: string; - signerHost: string; - network: string; - clientId: string; -} - export type EciesHex = { [key in keyof Ecies]: string; } & { mode?: string }; -export interface LegacyKeyAssignment { - Index: string; - PublicKey: { - X: string; - Y: string; - }; - Threshold: string; - Verifiers: Record; - Share: string; - Metadata: { - [key in keyof Ecies]: string; - }; -} export interface KeyAssignment { index: KeyIndex; public_key: { @@ -136,11 +100,6 @@ export interface KeyAssignment { nonce_data?: GetOrSetNonceResult; } -export interface LegacyShareRequestResult { - keys: LegacyKeyAssignment[]; - server_time_offset?: string; -} - export interface ShareRequestResult { keys: KeyAssignment[]; // these are encrypted ciphertexts diff --git a/src/torus.ts b/src/torus.ts index 9d1c91d..c7a8b63 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -1,56 +1,35 @@ -import { - INodePub, - JRPCResponse, - LEGACY_NETWORKS_ROUTE_MAP, - METADATA_MAP, - SIGNER_MAP, - TORUS_LEGACY_NETWORK_TYPE, - TORUS_NETWORK_TYPE, -} from "@toruslabs/constants"; -import { decrypt, Ecies, encrypt, generatePrivate, getPublic } from "@toruslabs/eccrypto"; -import { generateJsonRPCObject, get, post, setAPIKey, setEmbedHost } from "@toruslabs/http-helpers"; +import { INodePub, LEGACY_NETWORKS_ROUTE_MAP, METADATA_MAP, SIGNER_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE } from "@toruslabs/constants"; +import { Ecies, encrypt, generatePrivate } from "@toruslabs/eccrypto"; +import { setAPIKey, setEmbedHost } from "@toruslabs/http-helpers"; import BN from "bn.js"; import { curve, ec as EC } from "elliptic"; import stringify from "json-stable-stringify"; import { config } from "./config"; import { - calculateMedian, encParamsBufToHex, - generateAddressFromPrivKey, generateAddressFromPubKey, generateRandomPolynomial, getMetadata, - getNonce, getOrSetNonce, GetOrSetNonceError, GetPubKeyOrKeyAssign, - kCombinations, keccak256, - lagrangeInterpolation, - legacyKeyAssign, - legacyKeyLookup, - legacyWaitKeyLookup, retrieveOrImportShare, - thresholdSame, } from "./helpers"; import { - CommitmentRequestResult, GetOrSetNonceResult, ImportedShare, - LegacyShareRequestResult, LegacyVerifierLookupResponse, NonceMetadataParams, SetNonceData, TorusCtorOptions, TorusKey, TorusPublicKey, - UserType, v2NonceResultType, VerifierParams, } from "./interfaces"; import log from "./loglevel"; -import { Some } from "./some"; // Implement threshold logic wrappers around public APIs // of Torus nodes to handle malicious node responses @@ -69,8 +48,6 @@ class Torus { public enableOneKey: boolean; - private signerHost: string; - private legacyMetadataHost: string; constructor({ enableOneKey = false, clientId, network, serverTimeOffset = 0, allowHost, legacyMetadataHost }: TorusCtorOptions) { @@ -83,13 +60,6 @@ class Torus { this.allowHost = allowHost || `${SIGNER_MAP[network]}/api/allow`; this.enableOneKey = enableOneKey; this.legacyMetadataHost = legacyMetadataHost || METADATA_MAP[network as TORUS_LEGACY_NETWORK_TYPE]; - this.signerHost = `${SIGNER_MAP[network as TORUS_LEGACY_NETWORK_TYPE]}/api/sign`; - } - - public get isLegacyNetwork(): boolean { - const legacyNetwork = LEGACY_NETWORKS_ROUTE_MAP[this.network as TORUS_LEGACY_NETWORK_TYPE]; - if (legacyNetwork && !legacyNetwork.migrationCompleted) return true; - return false; } static enableLogging(v = true): void { @@ -130,7 +100,6 @@ class Torus { idToken: string, extraParams: Record = {} ): Promise { - if (this.isLegacyNetwork) return this.legacyRetrieveShares(endpoints, indexes, verifier, verifierParams, idToken, extraParams); return retrieveOrImportShare({ legacyMetadataHost: this.legacyMetadataHost, serverTimeOffset: this.serverTimeOffset, @@ -143,6 +112,7 @@ class Torus { verifier, verifierParams, idToken, + indexes, importedShares: [], extraParams: { ...extraParams, @@ -156,7 +126,6 @@ class Torus { torusNodePubs: INodePub[], { verifier, verifierId, extendedVerifierId }: { verifier: string; verifierId: string; extendedVerifierId?: string } ): Promise { - if (this.isLegacyNetwork) return this.getLegacyPublicAddress(endpoints, torusNodePubs, { verifier, verifierId }, this.enableOneKey); return this.getNewPublicAddress(endpoints, { verifier, verifierId, extendedVerifierId }, this.enableOneKey); } @@ -170,7 +139,6 @@ class Torus { newPrivateKey: string, extraParams: Record = {} ): Promise { - if (this.isLegacyNetwork) throw new Error("This function is not supported on legacy networks"); if (endpoints.length !== nodeIndexes.length) { throw new Error(`length of endpoints array must be same as length of nodeIndexes array`); } @@ -231,6 +199,7 @@ class Torus { verifier, verifierParams, idToken, + indexes: nodeIndexes, importedShares: sharesData, extraParams: { ...extraParams, @@ -248,367 +217,7 @@ class Torus { torusNodePubs: INodePub[], { verifier, verifierId, extendedVerifierId }: { verifier: string; verifierId: string; extendedVerifierId?: string } ): Promise { - if (!this.isLegacyNetwork) - return this.getNewPublicAddress(endpoints, { verifier, verifierId, extendedVerifierId }, true) as Promise; - return this.getLegacyPublicAddress(endpoints, torusNodePubs, { verifier, verifierId }, true); - } - - // this function is soon going to be deprecated - // this is only supported in celeste network currently. - private async legacyRetrieveShares( - endpoints: string[], - indexes: number[], - verifier: string, - verifierParams: VerifierParams, - idToken: string, - extraParams: Record = {} - ): Promise { - const promiseArr = []; - await get( - this.allowHost, - { - headers: { - verifier, - verifierid: verifierParams.verifier_id, - network: this.network, - clientid: this.clientId, - enablegating: "true", - }, - }, - { useAPIKey: true } - ); - /* - CommitmentRequestParams struct { - MessagePrefix string `json:"messageprefix"` - TokenCommitment string `json:"tokencommitment"` - TempPubX string `json:"temppubx"` - TempPubY string `json:"temppuby"` - VerifierIdentifier string `json:"verifieridentifier"` - } - */ - - // generate temporary private and public key that is used to secure receive shares - const tmpKey = generatePrivate(); - const pubKey = getPublic(tmpKey).toString("hex"); - const pubKeyX = pubKey.slice(2, 66); - const pubKeyY = pubKey.slice(66); - const tokenCommitment = keccak256(Buffer.from(idToken, "utf8")); - - // make commitment requests to endpoints - for (let i = 0; i < endpoints.length; i += 1) { - const p = post>( - endpoints[i], - generateJsonRPCObject("CommitmentRequest", { - messageprefix: "mug00", - tokencommitment: tokenCommitment.slice(2), - temppubx: pubKeyX, - temppuby: pubKeyY, - verifieridentifier: verifier, - }) - ).catch((err) => { - log.error("commitment", err); - }); - promiseArr.push(p); - } - /* - ShareRequestParams struct { - Item []bijson.RawMessage `json:"item"` - } - ShareRequestItem struct { - IDToken string `json:"idtoken"` - NodeSignatures []NodeSignature `json:"nodesignatures"` - VerifierIdentifier string `json:"verifieridentifier"` - } - NodeSignature struct { - Signature string - Data string - NodePubKeyX string - NodePubKeyY string - } - CommitmentRequestResult struct { - Signature string `json:"signature"` - Data string `json:"data"` - NodePubX string `json:"nodepubx"` - NodePubY string `json:"nodepuby"` - } - */ - // send share request once k + t number of commitment requests have completed - return Some, (void | JRPCResponse)[]>(promiseArr, (resultArr) => { - const completedRequests = resultArr.filter((x) => { - if (!x || typeof x !== "object") { - return false; - } - if (x.error) { - return false; - } - return true; - }); - if (completedRequests.length >= ~~(endpoints.length / 4) * 3 + 1) { - return Promise.resolve(resultArr); - } - return Promise.reject(new Error(`invalid ${JSON.stringify(resultArr)}`)); - }) - .then((responses) => { - const promiseArrRequest: Promise>[] = []; - const nodeSigs = []; - for (let i = 0; i < responses.length; i += 1) { - if (responses[i]) nodeSigs.push((responses[i] as JRPCResponse).result); - } - for (let i = 0; i < endpoints.length; i += 1) { - const p = post>( - endpoints[i], - generateJsonRPCObject("ShareRequest", { - encrypted: "yes", - client_time: Math.floor(Date.now() / 1000).toString(), - item: [{ ...verifierParams, idtoken: idToken, nodesignatures: nodeSigs, verifieridentifier: verifier, ...extraParams }], - }) - ).catch((err) => log.error("share req", err)); - promiseArrRequest.push(p); - } - return Some< - void | JRPCResponse, - { - privateKey: BN | undefined; - serverTimeOffset: number; - } - >(promiseArrRequest, async (shareResponses, sharedState) => { - /* - ShareRequestResult struct { - Keys []KeyAssignment - } - / KeyAssignmentPublic - - type KeyAssignmentPublic struct { - Index big.Int - PublicKey common.Point - Threshold int - Verifiers map[string][]string // Verifier => VerifierID - } - - // KeyAssignment - - type KeyAssignment struct { - KeyAssignmentPublic - Share big.Int // Or Si - } - */ - // check if threshold number of nodes have returned the same user public key - const completedRequests = shareResponses.filter((x) => x); - const thresholdPublicKey = thresholdSame( - shareResponses.map((x) => x && x.result && x.result.keys[0].PublicKey), - ~~(endpoints.length / 2) + 1 - ); - // optimistically run lagrange interpolation once threshold number of shares have been received - // this is matched against the user public key to ensure that shares are consistent - if (completedRequests.length >= ~~(endpoints.length / 2) + 1 && thresholdPublicKey) { - const sharePromises: Promise[] = []; - const nodeIndexes: BN[] = []; - const serverTimeOffsets: number[] = []; - for (let i = 0; i < shareResponses.length; i += 1) { - const currentShareResponse = shareResponses[i] as JRPCResponse; - const timeOffSet = currentShareResponse?.result?.server_time_offset; - const parsedTimeOffset = timeOffSet ? Number.parseInt(timeOffSet, 10) : 0; - serverTimeOffsets.push(parsedTimeOffset); - if (currentShareResponse?.result?.keys?.length > 0) { - currentShareResponse.result.keys.sort((a, b) => new BN(a.Index, 16).cmp(new BN(b.Index, 16))); - const firstKey = currentShareResponse.result.keys[0]; - if (firstKey.Metadata) { - const metadata = { - ephemPublicKey: Buffer.from(firstKey.Metadata.ephemPublicKey, "hex"), - iv: Buffer.from(firstKey.Metadata.iv, "hex"), - mac: Buffer.from(firstKey.Metadata.mac, "hex"), - // mode: Buffer.from(firstKey.Metadata.mode, "hex"), - }; - sharePromises.push( - decrypt(tmpKey, { - ...metadata, - ciphertext: Buffer.from(Buffer.from(firstKey.Share, "base64").toString("binary").padStart(64, "0"), "hex"), - }).catch((err) => log.error("share decryption", err)) - ); - } else { - sharePromises.push(Promise.resolve(Buffer.from(firstKey.Share.padStart(64, "0"), "hex"))); - } - } else { - sharePromises.push(Promise.resolve(undefined)); - } - nodeIndexes.push(new BN(indexes[i], 16)); - } - const sharesResolved = await Promise.all(sharePromises); - if (sharedState.resolved) return undefined; - - const decryptedShares = sharesResolved.reduce( - (acc, curr, index) => { - if (curr) acc.push({ index: nodeIndexes[index], value: new BN(curr) }); - return acc; - }, - [] as { index: BN; value: BN }[] - ); - // run lagrange interpolation on all subsets, faster in the optimistic scenario than berlekamp-welch due to early exit - const allCombis = kCombinations(decryptedShares.length, ~~(endpoints.length / 2) + 1); - let privateKey: BN | null = null; - for (let j = 0; j < allCombis.length; j += 1) { - const currentCombi = allCombis[j]; - const currentCombiShares = decryptedShares.filter((_, index) => currentCombi.includes(index)); - const shares = currentCombiShares.map((x) => x.value); - const indices = currentCombiShares.map((x) => x.index); - const derivedPrivateKey = lagrangeInterpolation(this.ec, shares, indices); - if (!derivedPrivateKey) continue; - const decryptedPubKey = getPublic(Buffer.from(derivedPrivateKey.toString(16, 64), "hex")).toString("hex"); - const decryptedPubKeyX = decryptedPubKey.slice(2, 66); - const decryptedPubKeyY = decryptedPubKey.slice(66); - if ( - new BN(decryptedPubKeyX, 16).cmp(new BN(thresholdPublicKey.X, 16)) === 0 && - new BN(decryptedPubKeyY, 16).cmp(new BN(thresholdPublicKey.Y, 16)) === 0 - ) { - privateKey = derivedPrivateKey; - break; - } - } - if (privateKey === undefined || privateKey === null) { - throw new Error("could not derive private key"); - } - return { privateKey, serverTimeOffset: this.serverTimeOffset || calculateMedian(serverTimeOffsets) }; - } - throw new Error("invalid"); - }); - }) - .then(async (keyData) => { - const { serverTimeOffset, privateKey: returnedOauthKey } = keyData; - const oAuthKey = returnedOauthKey; - - if (!oAuthKey) throw new Error("Invalid private key returned"); - const oAuthPubKey = getPublic(Buffer.from(oAuthKey.toString(16, 64), "hex")).toString("hex"); - const oAuthKeyX = oAuthPubKey.slice(2, 66); - const oAuthKeyY = oAuthPubKey.slice(66); - let metadataNonce: BN; - let finalPubKey: curve.base.BasePoint; - let typeOfUser: UserType = "v1"; - let pubKeyNonceResult: { X: string; Y: string } | undefined; - if (this.enableOneKey) { - const nonceResult = await getNonce(this.legacyMetadataHost, this.ec, serverTimeOffset, oAuthKeyX, oAuthKeyY, oAuthKey); - metadataNonce = new BN(nonceResult.nonce || "0", 16); - typeOfUser = nonceResult.typeOfUser; - if (typeOfUser === "v2") { - finalPubKey = this.ec - .keyFromPublic({ x: oAuthKeyX, y: oAuthKeyY }) - .getPublic() - .add( - this.ec - .keyFromPublic({ x: (nonceResult as v2NonceResultType).pubNonce.x, y: (nonceResult as v2NonceResultType).pubNonce.y }) - .getPublic() - ); - pubKeyNonceResult = { X: (nonceResult as v2NonceResultType).pubNonce.x, Y: (nonceResult as v2NonceResultType).pubNonce.y }; - } else { - // for imported keys in legacy networks - metadataNonce = await getMetadata(this.legacyMetadataHost, { pub_key_X: oAuthKeyX, pub_key_Y: oAuthKeyY }); - const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(this.ec.curve.n); - finalPubKey = this.ec.keyFromPrivate(privateKeyWithNonce.toString("hex"), "hex").getPublic(); - } - } else { - // for imported keys in legacy networks - metadataNonce = await getMetadata(this.legacyMetadataHost, { pub_key_X: oAuthKeyX, pub_key_Y: oAuthKeyY }); - const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(this.ec.curve.n); - finalPubKey = this.ec.keyFromPrivate(privateKeyWithNonce.toString("hex"), "hex").getPublic(); - } - - const oAuthKeyAddress = generateAddressFromPrivKey(this.ec, oAuthKey); - - let finalPrivKey = ""; // it is empty for v2 user upgraded to 2/n - if (typeOfUser === "v1" || (typeOfUser === "v2" && metadataNonce.gt(new BN(0)))) { - const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(this.ec.curve.n); - finalPrivKey = privateKeyWithNonce.toString("hex", 64).padStart(64, "0"); - } - - let isUpgraded: boolean | null = false; - if (typeOfUser === "v1") { - isUpgraded = null; - } else if (typeOfUser === "v2") { - isUpgraded = metadataNonce.eq(new BN("0")); - } - - // deriving address from pub key coz pubkey is always available - // but finalPrivKey won't be available for v2 user upgraded to 2/n - let finalEvmAddress = ""; - if (finalPubKey) { - finalEvmAddress = generateAddressFromPubKey(this.ec, finalPubKey.getX(), finalPubKey.getY()); - } else { - throw new Error("Invalid public key, this might be a bug, please report this to web3auth team"); - } - - return { - finalKeyData: { - evmAddress: finalEvmAddress, - X: finalPubKey ? finalPubKey.getX().toString(16, 64) : "", // this is final pub x user before and after updating to 2/n - Y: finalPubKey ? finalPubKey.getY().toString(16, 64) : "", // this is final pub y user before and after updating to 2/n - privKey: finalPrivKey, - }, - oAuthKeyData: { - evmAddress: oAuthKeyAddress, - X: oAuthKeyX, - Y: oAuthKeyY, - privKey: oAuthKey.toString("hex", 64).padStart(64, "0"), - }, - sessionData: { - sessionTokenData: [], - sessionAuthKey: "", - }, - metadata: { - pubNonce: pubKeyNonceResult, - nonce: metadataNonce, - typeOfUser: typeOfUser as UserType, - upgraded: isUpgraded, - serverTimeOffset, - }, - nodesData: { - nodeIndexes: [], - }, - }; - }); - } - - private async getLegacyPublicAddress( - endpoints: string[], - torusNodePubs: INodePub[], - { verifier, verifierId }: { verifier: string; verifierId: string }, - enableOneKey: boolean - ): Promise { - let finalKeyResult: LegacyVerifierLookupResponse | undefined; - let isNewKey = false; - - const { keyResult, errorResult, serverTimeOffset } = (await legacyKeyLookup(endpoints, verifier, verifierId)) || {}; - if (errorResult && JSON.stringify(errorResult).includes("Verifier not supported")) { - // change error msg - throw new Error(`Verifier not supported. Check if you: \n - 1. Are on the right network (Torus testnet/mainnet) \n - 2. Have setup a verifier on dashboard.web3auth.io?`); - } else if (errorResult && JSON.stringify(errorResult).includes("Verifier + VerifierID has not yet been assigned")) { - await legacyKeyAssign({ - endpoints, - torusNodePubs, - lastPoint: undefined, - firstPoint: undefined, - verifier, - verifierId, - signerHost: this.signerHost, - network: this.network, - clientId: this.clientId, - }); - const assignResult = await legacyWaitKeyLookup(endpoints, verifier, verifierId, 1000); - finalKeyResult = assignResult?.keyResult; - isNewKey = true; - } else if (keyResult) { - finalKeyResult = keyResult; - } else { - throw new Error(`node results do not match at first lookup ${JSON.stringify(keyResult || {})}, ${JSON.stringify(errorResult || {})}`); - } - if (finalKeyResult) { - const finalServerTimeOffset = this.serverTimeOffset || serverTimeOffset; - return this.formatLegacyPublicKeyData({ - finalKeyResult, - isNewKey, - enableOneKey, - serverTimeOffset: finalServerTimeOffset, - }); - } - throw new Error(`node results do not match at final lookup ${JSON.stringify(keyResult || {})}, ${JSON.stringify(errorResult || {})}`); + return this.getNewPublicAddress(endpoints, { verifier, verifierId, extendedVerifierId }, true) as Promise; } private generateNonceMetadataParams(operation: string, privateKey: BN, nonce?: BN): NonceMetadataParams { diff --git a/test/aqua.test.ts b/test/aqua.test.ts index 34485f6..4fa4fde 100644 --- a/test/aqua.test.ts +++ b/test/aqua.test.ts @@ -23,6 +23,7 @@ describe("torus utils aqua", function () { }); TORUS_NODE_MANAGER = new NodeManager({ network: TORUS_LEGACY_NETWORK.AQUA }); }); + it("should fetch public address", async function () { const verifier = "tkey-google-aqua"; // any verifier const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; diff --git a/test/celeste.test.ts b/test/celeste.test.ts index 7b326b6..7623295 100644 --- a/test/celeste.test.ts +++ b/test/celeste.test.ts @@ -23,25 +23,26 @@ describe("torus utils celeste", function () { }); TORUS_NODE_MANAGER = new NodeManager({ network: TORUS_LEGACY_NETWORK.CELESTE }); }); + it("should fetch public address", async function () { const verifier = "tkey-google-celeste"; // any verifier const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242"); + expect(result.finalKeyData.evmAddress).to.equal("0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242", - X: "d1a99fbec9326f04687daea4261b15b68cc45671554d43e94529d62857bf236c", - Y: "085bc72609f474b7b80081ecdc92d0dca241327195c7655c7a35b601c1f93e8e", + X: "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9", + Y: "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb", + evmAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", }, finalKeyData: { - evmAddress: "0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242", - X: "d1a99fbec9326f04687daea4261b15b68cc45671554d43e94529d62857bf236c", - Y: "085bc72609f474b7b80081ecdc92d0dca241327195c7655c7a35b601c1f93e8e", + X: "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9", + Y: "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb", + evmAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", }, metadata: { pubNonce: undefined, @@ -58,21 +59,21 @@ describe("torus utils celeste", function () { const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result1 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(result1.finalKeyData.evmAddress).to.equal("0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242"); + expect(result1.finalKeyData.evmAddress).to.equal("0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113"); expect(result1.metadata.typeOfUser).to.equal("v1"); expect(result1.metadata.serverTimeOffset).lessThan(20); delete result1.metadata.serverTimeOffset; expect(result1).eql({ oAuthKeyData: { - evmAddress: "0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242", - X: "d1a99fbec9326f04687daea4261b15b68cc45671554d43e94529d62857bf236c", - Y: "085bc72609f474b7b80081ecdc92d0dca241327195c7655c7a35b601c1f93e8e", + X: "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9", + Y: "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb", + evmAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", }, finalKeyData: { - evmAddress: "0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242", - X: "d1a99fbec9326f04687daea4261b15b68cc45671554d43e94529d62857bf236c", - Y: "085bc72609f474b7b80081ecdc92d0dca241327195c7655c7a35b601c1f93e8e", + X: "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9", + Y: "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb", + evmAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", }, metadata: { pubNonce: undefined, @@ -90,26 +91,29 @@ describe("torus utils celeste", function () { verifier: v2Verifier, verifierId: v2TestEmail, }); - expect(result2.finalKeyData.evmAddress).to.equal("0x69fB3A96016817F698a1279aE2d65F3916F3Db6F"); - expect(result2.metadata.typeOfUser).to.equal("v1"); + expect(result2.finalKeyData.evmAddress).to.equal("0x8d69CE354DA39413f205FdC8680dE1F3FBBb36e2"); + expect(result2.metadata.typeOfUser).to.equal("v2"); delete result2.metadata.serverTimeOffset; expect(result2).eql({ oAuthKeyData: { - evmAddress: "0x69fB3A96016817F698a1279aE2d65F3916F3Db6F", - X: "9180a724488c99d7639f886e1920598618c2e599481d71ffd9f602c8a856ff20", - Y: "c5da5c13fedf3a22964ab39afb871bff607479e2a5cb2e621608771b4276b44b", + X: "cfa646a2949ebe559205c5c407d734d1b6927f2ea5fbeabfcbc31ab9a985a336", + Y: "8f988eb8b59515293820aa38af172b153e8d25307db8d5f410407c20e062b6e6", + evmAddress: "0xda4afB35493094Dd2C05b186Ca0FABAD96491B21", }, finalKeyData: { - evmAddress: "0x69fB3A96016817F698a1279aE2d65F3916F3Db6F", - X: "9180a724488c99d7639f886e1920598618c2e599481d71ffd9f602c8a856ff20", - Y: "c5da5c13fedf3a22964ab39afb871bff607479e2a5cb2e621608771b4276b44b", + X: "5962144e03b993b0e503eb4e6e0196427f9fc9472f0dfd1be2ca5d4939f91680", + Y: "f6e81f01f483110badab18371237d15834f9ecf31c3588c165dae32ec446ac38", + evmAddress: "0x8d69CE354DA39413f205FdC8680dE1F3FBBb36e2", }, metadata: { - pubNonce: undefined, + pubNonce: { + X: "2f630074151394ba1f715986a9215f4e36c9f22fc264ff880ef6d162c1300aa8", + Y: "704cb63e5f7a291735c54e22242ef53673642ec1660da00f1abc2e7909da03d7", + }, nonce: new BN(0), upgraded: false, - typeOfUser: "v1", + typeOfUser: "v2", }, nodesData: { nodeIndexes: [] }, }); @@ -122,24 +126,27 @@ describe("torus utils celeste", function () { }); delete result3.metadata.serverTimeOffset; - expect(result3.finalKeyData.evmAddress).to.equal("0x24aCac36F8A4bD93052207dA410dA71AF92258b7"); - expect(result3.metadata.typeOfUser).to.equal("v1"); + expect(result3.finalKeyData.evmAddress).to.equal("0x8108c29976C458e76f797AD55A3715Ce80a3fe78"); + expect(result3.metadata.typeOfUser).to.equal("v2"); expect(result3).eql({ oAuthKeyData: { - evmAddress: "0x24aCac36F8A4bD93052207dA410dA71AF92258b7", - X: "95b242e13e394e252d9685bfc1937a2acfa25e0c5e1d37bfd5247879ae1468cc", - Y: "687a6754180aec931ff65e55a058032107df519334b2f5c6fb1fc5157620a219", + X: "0cc857201e6c304dd893b243e323fe95982e5a99c0994cf902efa2432a672eb4", + Y: "37a2f53c250b3e1186e38ece3dfcbcb23e325913038703531831b96d3e7b54cc", + evmAddress: "0xc8c4748ec135196fb482C761da273C31Ec48B099", }, finalKeyData: { - evmAddress: "0x24aCac36F8A4bD93052207dA410dA71AF92258b7", - X: "95b242e13e394e252d9685bfc1937a2acfa25e0c5e1d37bfd5247879ae1468cc", - Y: "687a6754180aec931ff65e55a058032107df519334b2f5c6fb1fc5157620a219", + X: "e95fe2d595ade03f56d9c9a147fbb67705041704f147576fa4a8afbe7dc69470", + Y: "3e20e4b331466769c4dd78f4561bfb2849010b4005b09c2ed082380326724ebe", + evmAddress: "0x8108c29976C458e76f797AD55A3715Ce80a3fe78", }, metadata: { - pubNonce: undefined, + pubNonce: { + X: "f8ff2c44cc0abf512d35b35c3c5cbc0eda700d49bc13b72c5492b0cdb2ca3619", + Y: "88fb3087cec269c8c39d25b04f15298d33712f13b0f9665821328dfc7a567afb", + }, nonce: new BN(0), upgraded: false, - typeOfUser: "v1", + typeOfUser: "v2", }, nodesData: { nodeIndexes: [] }, }); @@ -182,9 +189,9 @@ describe("torus utils celeste", function () { Y: "6d28c46c5385b90322bde74d6c5096e154eae2838399f4d6e8d752f7b0c449c1", privKey: "0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914", }, - sessionData: { sessionTokenData: [], sessionAuthKey: "" }, + sessionData: result.sessionData, metadata: { pubNonce: undefined, nonce: new BN(0), typeOfUser: "v1", upgraded: null }, - nodesData: { nodeIndexes: [] }, + nodesData: result.nodesData, }); }); @@ -223,9 +230,9 @@ describe("torus utils celeste", function () { Y: "bfd29ab1e97b3f7c444bb3e7ad0acb39d72589371387436c7d623d1e83f3d6eb", privKey: "356305761eca57f27b09700d76456ad627b084152725dbfdfcfa0abcd9d4f17e", }, - sessionData: { sessionTokenData: [], sessionAuthKey: "" }, + sessionData: result.sessionData, metadata: { pubNonce: undefined, nonce: new BN(0), typeOfUser: "v1", upgraded: null }, - nodesData: { nodeIndexes: [] }, + nodesData: result.nodesData, }); }); }); diff --git a/test/cyan.test.ts b/test/cyan.test.ts index 1c72102..f0c4792 100644 --- a/test/cyan.test.ts +++ b/test/cyan.test.ts @@ -23,6 +23,7 @@ describe("torus utils cyan", function () { }); TORUS_NODE_MANAGER = new NodeManager({ network: TORUS_LEGACY_NETWORK.CYAN }); }); + it("should fetch public address", async function () { const verifier = "tkey-google-cyan"; // any verifier const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; diff --git a/test/index.html b/test/index.html index d099e0b..f0f72a4 100644 --- a/test/index.html +++ b/test/index.html @@ -1,4 +1,4 @@ - + Test Torus.js diff --git a/test/mainnet.test.ts b/test/mainnet.test.ts index d5c01d8..2ee12b2 100644 --- a/test/mainnet.test.ts +++ b/test/mainnet.test.ts @@ -23,6 +23,7 @@ describe("torus utils mainnet", function () { network: TORUS_LEGACY_NETWORK.MAINNET, }); }); + it("should fetch public address", async function () { const verifier = "google"; // any verifier const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index e697754..a2605b5 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -238,6 +238,7 @@ describe("torus utils sapphire devnet", function () { nodesData: result.nodesData, }); }); + it("should fetch public address of imported user", async function () { const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_IMPORT_EMAIL }; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); @@ -483,6 +484,7 @@ describe("torus utils sapphire devnet", function () { nodesData: result.nodesData, }); }); + it("should assign key to tss verifier id", async function () { const email = faker.internet.email(); const nonce = 0; @@ -600,6 +602,7 @@ describe("torus utils sapphire devnet", function () { nodesData: result.nodesData, }); }); + it("should be able to login when verifierID hash enabled", async function () { const token = generateIdToken(TORUS_HASH_ENABLED_TEST_EMAIL, "ES256"); const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_HASH_ENABLED_TEST_EMAIL }; diff --git a/test/sapphire_mainnet.test.ts b/test/sapphire_mainnet.test.ts index b4d0aef..559011b 100644 --- a/test/sapphire_mainnet.test.ts +++ b/test/sapphire_mainnet.test.ts @@ -27,6 +27,7 @@ describe("torus utils sapphire mainnet", function () { }); TORUS_NODE_MANAGER = new NodeManager({ network: TORUS_SAPPHIRE_NETWORK.SAPPHIRE_MAINNET }); }); + it("should fetch public address", async function () { const verifier = "tkey-google-sapphire-mainnet"; // any verifier const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; @@ -60,7 +61,7 @@ describe("torus utils sapphire mainnet", function () { }); }); - it("should be able to import a key for a new user", async function () { + it.skip("should be able to import a key for a new user", async function () { const email = faker.internet.email(); const token = generateIdToken(email, "ES256"); const privKeyBuffer = generatePrivate(); @@ -78,6 +79,7 @@ describe("torus utils sapphire mainnet", function () { ); expect(result.finalKeyData.privKey).to.be.equal(privHex); }); + it("should be able to key assign", async function () { const verifier = "tkey-google-sapphire-mainnet"; // any verifier const email = faker.internet.email(); @@ -228,6 +230,7 @@ describe("torus utils sapphire mainnet", function () { nodesData: result.nodesData, }); }); + it("should be able to login when verifierID hash enabled", async function () { const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL }; diff --git a/test/testnet.test.ts b/test/testnet.test.ts index 30f311f..719c67e 100644 --- a/test/testnet.test.ts +++ b/test/testnet.test.ts @@ -24,6 +24,7 @@ describe("torus utils migrated testnet on sapphire", function () { network: TORUS_LEGACY_NETWORK.TESTNET, }); }); + it("should fetch public address", async function () { const verifier = "google-lrc"; // any verifier const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; @@ -246,6 +247,7 @@ describe("torus utils migrated testnet on sapphire", function () { nodesData: result.nodesData, }); }); + it("should fail at get or set nonce when server time offset is expired", async function () { const email = "himanshu@tor.us"; const verifier = "google-lrc";