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

fetch nonce from metadata server if nodes doesnt return #144

Merged
merged 3 commits into from
May 14, 2024
Merged
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
2 changes: 2 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export const JRPC_METHODS = {
IMPORT_SHARE: "ImportShare",
GET_SHARE_OR_KEY_ASSIGN: "GetShareOrKeyAssign",
};

export const SAPPHIRE_METADATA_URL = "https://node-1.node.web3auth.io/metadata";
11 changes: 11 additions & 0 deletions src/helpers/metadataUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ec } from "elliptic";
import stringify from "json-stable-stringify";
import log from "loglevel";

import { SAPPHIRE_METADATA_URL } from "../constants";
import { EciesHex, GetOrSetNonceResult, MetadataParams } from "../interfaces";
import { encParamsHexToBuf } from "./common";
import { keccak256 } from "./keyUtils";
Expand Down Expand Up @@ -90,3 +91,13 @@ export async function getNonce(
): Promise<GetOrSetNonceResult> {
return getOrSetNonce(legacyMetadataHost, ecCurve, serverTimeOffset, X, Y, privKey, true);
}

export async function getOrSetSapphireMetadataNonce(X: string, Y: string): Promise<GetOrSetNonceResult> {
const data = {
pub_key_X: X,
pub_key_Y: Y,
key_type: "secp256k1",
set_data: { operation: "getOrSetNonce" },
};
return post<GetOrSetNonceResult>(`${SAPPHIRE_METADATA_URL}/get_or_set_nonce`, data, undefined, { useAPIKey: true });
}
25 changes: 20 additions & 5 deletions src/helpers/nodeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { Some } from "../some";
import { calculateMedian, kCombinations, normalizeKeysResult, thresholdSame } from "./common";
import { generateAddressFromPrivKey, generateAddressFromPubKey, keccak256 } from "./keyUtils";
import { lagrangeInterpolation } from "./langrangeInterpolatePoly";
import { decryptNodeData, getMetadata, getOrSetNonce } from "./metadataUtils";
import { decryptNodeData, getMetadata, getOrSetNonce, getOrSetSapphireMetadataNonce } from "./metadataUtils";

export const GetPubKeyOrKeyAssign = async (params: {
endpoints: string[];
Expand Down Expand Up @@ -56,7 +56,7 @@ export const GetPubKeyOrKeyAssign = async (params: {

let nonceResult: GetOrSetNonceResult | undefined;
const nodeIndexes: number[] = [];
const result = await Some<void | JRPCResponse<VerifierLookupResponse>, KeyLookupResult>(lookupPromises, (lookupResults) => {
const result = await Some<void | JRPCResponse<VerifierLookupResponse>, KeyLookupResult>(lookupPromises, async (lookupResults) => {
const lookupPubKeys = lookupResults.filter((x1) => {
if (x1 && !x1.error) {
return x1;
Expand Down Expand Up @@ -88,6 +88,15 @@ export const GetPubKeyOrKeyAssign = async (params: {
}
}
}

// if nonce result is not returned by nodes, fetch directly from metadata
if (!nonceResult) {
const metadataNonceResult = await getOrSetSapphireMetadataNonce(keyResult.keys[0].pub_key_X, keyResult.keys[0].pub_key_Y);
// rechecking nonceResult to avoid promise race condition.
if (!nonceResult && metadataNonceResult) {
nonceResult = metadataNonceResult;
}
}
}

const serverTimeOffsets: number[] = [];
Expand Down Expand Up @@ -369,9 +378,15 @@ export async function retrieveOrImportShare(params: {
// if both thresholdNonceData and extended_verifier_id are not available
// then we need to throw other wise address would be incorrect.
if (!thresholdNonceData && !verifierParams.extended_verifier_id && !LEGACY_NETWORKS_ROUTE_MAP[network as TORUS_LEGACY_NETWORK_TYPE]) {
throw new Error(
`invalid metadata result from nodes, nonce metadata is empty for verifier: ${verifier} and verifierId: ${verifierParams.verifier_id}`
);
const metadataNonceResult = await getOrSetSapphireMetadataNonce(thresholdPublicKey.X, thresholdPublicKey.Y);
// rechecking nonceResult to avoid promise race condition.
if (metadataNonceResult && !thresholdNonceData) {
thresholdNonceData = metadataNonceResult;
} else {
throw new Error(
`invalid metadata result from nodes, nonce metadata is empty for verifier: ${verifier} and verifierId: ${verifierParams.verifier_id}`
);
}
}

const thresholdReqCount = importedShares.length > 0 ? endpoints.length : minThreshold;
Expand Down
4 changes: 2 additions & 2 deletions src/some.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export class SomeError<T> extends Error {
// temp key should not be logged anywhere
const message = `Unable to resolve enough promises.
errors: ${errors.map((x) => x?.message || x).join(", ")},
predicate error: ${predicate},
${responses.length} responses,
responses: ${JSON.stringify(responses)},
predicate error: ${predicate}`;
responses: ${JSON.stringify(responses)}`;
super(message);
this.errors = errors;
this.responses = responses;
Expand Down
2 changes: 1 addition & 1 deletion test/testnet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ describe("torus utils migrated testnet on sapphire", function () {
network: TORUS_LEGACY_NETWORK.TESTNET,
clientId: "YOUR_CLIENT_ID",
enableOneKey: true,
serverTimeOffset: -100,
serverTimeOffset: -700,
});
const { torusNodeSSSEndpoints: torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails);
try {
Expand Down
Loading