Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added get key or import shares #172

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
76 changes: 56 additions & 20 deletions src/helpers/nodeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, unknown>[] = [];
for (let i = 0; i < endpoints.length; i += 1) {
Expand Down Expand Up @@ -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<string, unknown>[] = [];
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<JRPCResponse<ImportShareRequestResult[]>>(
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<JRPCResponse<ShareRequestResult>>(
endpoints[i],
Expand Down Expand Up @@ -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
Expand Down
88 changes: 47 additions & 41 deletions test/sapphire_devnet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 () {
Expand Down
Loading