From f1aae98c06e950cb1eec120a9ed54d66eaf3bb21 Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 23 Jan 2025 11:25:17 +0530 Subject: [PATCH 1/4] added get key or import shares --- src/constants.ts | 1 + src/helpers/nodeUtils.ts | 76 +++++++++++++++++++++++-------- test/sapphire_devnet.test.ts | 88 +++++++++++++++++++----------------- 3 files changed, 104 insertions(+), 61 deletions(-) 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..7bef766 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -451,28 +451,16 @@ 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, we need to get existing key or import new shares from client + const getExistingKeyOrImportNewShares = !useDkg; + if (overrideExistingKey) { + console.log("importing new shares"); + isImportingShares = true; const proxyEndpointNum = getProxyCoordinatorEndpointIndex(endpoints, verifier, verifierParams.verifier_id); const items: Record[] = []; for (let i = 0; i < endpoints.length; i += 1) { @@ -515,7 +503,55 @@ export async function retrieveOrImportShare(params: { { logTracingHeader: config.logRequestTracing } ).catch((err) => log.error("share req", err)); promiseArrRequest.push(p); + } else if (getExistingKeyOrImportNewShares) { + console.log("importing new shares or fetch existing key"); + + isImportingShares = true; + 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 { + console.log("fetch existing shares or assign new key with dkg"); for (let i = 0; i < endpoints.length; i += 1) { const p = post>( endpoints[i], @@ -610,7 +646,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/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index 8cc2e8f..e79f22b 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -315,56 +315,62 @@ describe("torus utils sapphire devnet", function () { expect(result.finalKeyData.walletAddress).to.not.equal(null); }); - it("should be able to login", async function () { - const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }); + it.only("should be able to login", async function () { + const email = `${faker.internet.email()}`; + + const token = generateIdToken(email, "ES256"); + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: email }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( getRetrieveSharesParams( torusNodeEndpoints, nodeDetails.torusIndexes, TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, + { verifier_id: email }, token, - nodeDetails.torusNodePub + nodeDetails.torusNodePub, + {}, + false, + false ) ); - expect(result.metadata.serverTimeOffset).lessThan(20); - delete result.metadata.serverTimeOffset; - - expect(result).eql({ - finalKeyData: { - walletAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", - X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", - Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", - privKey: "230dad9f42039569e891e6b066ff5258b14e9764ef5176d74aeb594d1a744203", - }, - oAuthKeyData: { - walletAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", - X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", - Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", - privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", - }, - postboxKeyData: { - X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", - Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", - privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", - }, - sessionData: { - sessionTokenData: result.sessionData.sessionTokenData, - sessionAuthKey: result.sessionData.sessionAuthKey, - }, - metadata: { - pubNonce: { - X: "5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc", - Y: "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed", - }, - nonce: new BN("b7d126751b68ecd09e371a23898e6819dee54708a5ead4f6fe83cdc79c0f1c4a", "hex"), - typeOfUser: "v2", - upgraded: false, - }, - nodesData: result.nodesData, - }); + console.log(result.finalKeyData.walletAddress); + // expect(result.metadata.serverTimeOffset).lessThan(20); + // delete result.metadata.serverTimeOffset; + + // expect(result).eql({ + // finalKeyData: { + // walletAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", + // X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", + // Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", + // privKey: "230dad9f42039569e891e6b066ff5258b14e9764ef5176d74aeb594d1a744203", + // }, + // oAuthKeyData: { + // walletAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + // X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", + // Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", + // privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", + // }, + // postboxKeyData: { + // X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", + // Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", + // privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", + // }, + // sessionData: { + // sessionTokenData: result.sessionData.sessionTokenData, + // sessionAuthKey: result.sessionData.sessionAuthKey, + // }, + // metadata: { + // pubNonce: { + // X: "5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc", + // Y: "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed", + // }, + // nonce: new BN("b7d126751b68ecd09e371a23898e6819dee54708a5ead4f6fe83cdc79c0f1c4a", "hex"), + // typeOfUser: "v2", + // upgraded: false, + // }, + // nodesData: result.nodesData, + // }); }); it("should be able to login without commitments", async function () { From 4e1d0e3b48d779229e0dabd3c0841bcf5a213e29 Mon Sep 17 00:00:00 2001 From: himanshu Date: Fri, 7 Feb 2025 09:16:14 +0530 Subject: [PATCH 2/4] cleanup --- src/helpers/nodeUtils.ts | 5 --- test/sapphire_devnet.test.ts | 75 ++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 43 deletions(-) diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 7bef766..45b786e 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -459,7 +459,6 @@ export async function retrieveOrImportShare(params: { // if dkg is not used, we need to get existing key or import new shares from client const getExistingKeyOrImportNewShares = !useDkg; if (overrideExistingKey) { - console.log("importing new shares"); isImportingShares = true; const proxyEndpointNum = getProxyCoordinatorEndpointIndex(endpoints, verifier, verifierParams.verifier_id); const items: Record[] = []; @@ -504,9 +503,6 @@ export async function retrieveOrImportShare(params: { ).catch((err) => log.error("share req", err)); promiseArrRequest.push(p); } else if (getExistingKeyOrImportNewShares) { - console.log("importing new shares or fetch existing key"); - - isImportingShares = true; const proxyEndpointNum = getProxyCoordinatorEndpointIndex(endpoints, verifier, verifierParams.verifier_id); const items: Record[] = []; for (let i = 0; i < endpoints.length; i += 1) { @@ -551,7 +547,6 @@ export async function retrieveOrImportShare(params: { ).catch((err) => log.error("share req", err)); promiseArrRequest.push(p); } else { - console.log("fetch existing shares or assign new key with dkg"); for (let i = 0; i < endpoints.length; i += 1) { const p = post>( endpoints[i], diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index e79f22b..25e8911 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -315,7 +315,7 @@ describe("torus utils sapphire devnet", function () { expect(result.finalKeyData.walletAddress).to.not.equal(null); }); - it.only("should be able to login", async function () { + it("should be able to login", async function () { const email = `${faker.internet.email()}`; const token = generateIdToken(email, "ES256"); @@ -334,43 +334,42 @@ describe("torus utils sapphire devnet", function () { false ) ); - console.log(result.finalKeyData.walletAddress); - // expect(result.metadata.serverTimeOffset).lessThan(20); - // delete result.metadata.serverTimeOffset; - - // expect(result).eql({ - // finalKeyData: { - // walletAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", - // X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", - // Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", - // privKey: "230dad9f42039569e891e6b066ff5258b14e9764ef5176d74aeb594d1a744203", - // }, - // oAuthKeyData: { - // walletAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", - // X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", - // Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", - // privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", - // }, - // postboxKeyData: { - // X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", - // Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", - // privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", - // }, - // sessionData: { - // sessionTokenData: result.sessionData.sessionTokenData, - // sessionAuthKey: result.sessionData.sessionAuthKey, - // }, - // metadata: { - // pubNonce: { - // X: "5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc", - // Y: "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed", - // }, - // nonce: new BN("b7d126751b68ecd09e371a23898e6819dee54708a5ead4f6fe83cdc79c0f1c4a", "hex"), - // typeOfUser: "v2", - // upgraded: false, - // }, - // nodesData: result.nodesData, - // }); + expect(result.metadata.serverTimeOffset).lessThan(20); + delete result.metadata.serverTimeOffset; + + expect(result).eql({ + finalKeyData: { + walletAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", + X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", + Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", + privKey: "230dad9f42039569e891e6b066ff5258b14e9764ef5176d74aeb594d1a744203", + }, + oAuthKeyData: { + walletAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", + Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", + privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", + }, + postboxKeyData: { + X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", + Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", + privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", + }, + sessionData: { + sessionTokenData: result.sessionData.sessionTokenData, + sessionAuthKey: result.sessionData.sessionAuthKey, + }, + metadata: { + pubNonce: { + X: "5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc", + Y: "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed", + }, + nonce: new BN("b7d126751b68ecd09e371a23898e6819dee54708a5ead4f6fe83cdc79c0f1c4a", "hex"), + typeOfUser: "v2", + upgraded: false, + }, + nodesData: result.nodesData, + }); }); it("should be able to login without commitments", async function () { From 5a96dee0f91b5f109048ed0fba1b801930d7bab7 Mon Sep 17 00:00:00 2001 From: himanshu Date: Fri, 7 Feb 2025 12:15:23 +0530 Subject: [PATCH 3/4] fix devnet test --- test/sapphire_devnet.test.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index 25e8911..2f7e819 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -316,22 +316,18 @@ describe("torus utils sapphire devnet", function () { }); it("should be able to login", async function () { - const email = `${faker.internet.email()}`; - - const token = generateIdToken(email, "ES256"); - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: email }); + const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( getRetrieveSharesParams( torusNodeEndpoints, nodeDetails.torusIndexes, TORUS_TEST_VERIFIER, - { verifier_id: email }, + { verifier_id: TORUS_TEST_EMAIL }, token, nodeDetails.torusNodePub, - {}, - false, - false + {} ) ); expect(result.metadata.serverTimeOffset).lessThan(20); From eeb9e66823111c394b344c2c56d59bed707dee1c Mon Sep 17 00:00:00 2001 From: himanshu Date: Fri, 7 Feb 2025 13:00:12 +0530 Subject: [PATCH 4/4] fix tests --- src/helpers/nodeUtils.ts | 8 ++++++-- test/onekey.test.ts | 2 +- test/sapphire_devnet.test.ts | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 45b786e..bbae09e 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -456,9 +456,11 @@ export async function retrieveOrImportShare(params: { const promiseArrRequest = []; - // if dkg is not used, we need to get existing key or import new shares from client - const getExistingKeyOrImportNewShares = !useDkg; + // 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[] = []; @@ -503,6 +505,7 @@ export async function retrieveOrImportShare(params: { ).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) { @@ -547,6 +550,7 @@ export async function retrieveOrImportShare(params: { ).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], 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 2f7e819..5c6126e 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -381,7 +381,7 @@ describe("torus utils sapphire devnet", function () { token, nodeDetails.torusNodePub, {}, - true, + false, false ) );