diff --git a/src/constants.ts b/src/constants.ts index 1f449aa..fcea33b 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -4,6 +4,7 @@ export const JRPC_METHODS = { COMMITMENT_REQUEST: "CommitmentRequest", IMPORT_SHARES: "ImportShares", GET_SHARE_OR_KEY_ASSIGN: "GetShareOrKeyAssign", + GET_KEY_OR_IMPORT_SHARES: "GetKeyOrImportShares", }; export const SAPPHIRE_METADATA_URL = "https://node-1.node.web3auth.io/metadata"; diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index feb291b..bbae09e 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -451,28 +451,17 @@ export async function retrieveOrImportShare(params: { nodeSigs.map((x) => x && x.pub_key_x), halfThreshold ); - } else if (!checkCommitment && finalImportedShares.length > 0) { - // in case not allowed to override existing key for import request - // check if key exists - if (!overrideExistingKey) { - const keyLookupResult = await VerifierLookupRequest({ endpoints, verifier, verifierId: verifierParams.verifier_id, keyType }); - if ( - keyLookupResult.errorResult && - !(keyLookupResult.errorResult?.data as string)?.includes("Verifier + VerifierID has not yet been assigned") - ) { - throw new Error( - `node results do not match at first lookup ${JSON.stringify(keyLookupResult.keyResult || {})}, ${JSON.stringify(keyLookupResult.errorResult || {})}` - ); - } - if (keyLookupResult.keyResult?.keys?.length > 0) { - isExistingKey = !!keyLookupResult.keyResult.keys[0]; - } - } } + let isImportingShares = false; + const promiseArrRequest = []; - const canImportedShares = overrideExistingKey || (!useDkg && !isExistingKey); - if (canImportedShares) { + // if dkg is not used and may be its not a existing key, + // we need to get existing key or import new shares from client + const getExistingKeyOrImportNewShares = !useDkg && !isExistingKey; + if (overrideExistingKey) { + // import new key flow + isImportingShares = true; const proxyEndpointNum = getProxyCoordinatorEndpointIndex(endpoints, verifier, verifierParams.verifier_id); const items: Record[] = []; for (let i = 0; i < endpoints.length; i += 1) { @@ -515,7 +504,53 @@ export async function retrieveOrImportShare(params: { { logTracingHeader: config.logRequestTracing } ).catch((err) => log.error("share req", err)); promiseArrRequest.push(p); + } else if (getExistingKeyOrImportNewShares) { + // no dkg login and registration flow + const proxyEndpointNum = getProxyCoordinatorEndpointIndex(endpoints, verifier, verifierParams.verifier_id); + const items: Record[] = []; + for (let i = 0; i < endpoints.length; i += 1) { + const importedShare = finalImportedShares[i]; + if (!importedShare) { + throw new Error(`invalid imported share at index ${i}`); + } + items.push({ + ...verifierParams, + idtoken: idToken, + nodesignatures: nodeSigs, + verifieridentifier: verifier, + pub_key_x: importedShare.oauth_pub_key_x, + pub_key_y: importedShare.oauth_pub_key_y, + signing_pub_key_x: importedShare.signing_pub_key_x, + signing_pub_key_y: importedShare.signing_pub_key_y, + encrypted_share: importedShare.encrypted_share, + encrypted_share_metadata: importedShare.encrypted_share_metadata, + node_index: importedShare.node_index, + key_type: importedShare.key_type, + nonce_data: importedShare.nonce_data, + nonce_signature: importedShare.nonce_signature, + sss_endpoint: endpoints[i], + ...extraParams, + }); + } + const p = post>( + endpoints[proxyEndpointNum], + generateJsonRPCObject(JRPC_METHODS.GET_KEY_OR_IMPORT_SHARES, { + encrypted: "yes", + use_temp: true, + verifieridentifier: verifier, + distributed_metadata: true, + temppubx: nodeSigs.length === 0 && !checkCommitment ? sessionPubX : "", // send session pub key x only if node signatures are not available (Ie. in non commitment flow) + temppuby: nodeSigs.length === 0 && !checkCommitment ? sessionPubY : "", // send session pub key y only if node signatures are not available (Ie. in non commitment flow) + item: items, + key_type: keyType, + one_key_flow: true, + }), + {}, + { logTracingHeader: config.logRequestTracing } + ).catch((err) => log.error("share req", err)); + promiseArrRequest.push(p); } else { + // dkg login and registration flow for (let i = 0; i < endpoints.length; i += 1) { const p = post>( endpoints[i], @@ -610,7 +645,7 @@ export async function retrieveOrImportShare(params: { } }); - const thresholdReqCount = canImportedShares ? endpoints.length : halfThreshold; + const thresholdReqCount = isImportingShares && !isExistingKey ? endpoints.length : halfThreshold; // 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 diff --git a/test/onekey.test.ts b/test/onekey.test.ts index 3b5890a..73811c9 100644 --- a/test/onekey.test.ts +++ b/test/onekey.test.ts @@ -177,7 +177,7 @@ describe("torus onekey", function () { expect(publicAddress.oAuthKeyData.walletAddress).to.not.equal(null); }); - it("should be able to key assign via login", async function () { + it.only("should be able to key assign via login", async function () { const email = faker.internet.email(); const token = generateIdToken(email, "ES256"); const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email }; diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index 8cc2e8f..5c6126e 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -326,7 +326,8 @@ describe("torus utils sapphire devnet", function () { TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, - nodeDetails.torusNodePub + nodeDetails.torusNodePub, + {} ) ); expect(result.metadata.serverTimeOffset).lessThan(20); @@ -380,7 +381,7 @@ describe("torus utils sapphire devnet", function () { token, nodeDetails.torusNodePub, {}, - true, + false, false ) );