diff --git a/.gitignore b/.gitignore index 9f6504c..a1b106c 100644 --- a/.gitignore +++ b/.gitignore @@ -104,3 +104,4 @@ dist .tern-port .env.test +**/*.DS_Store diff --git a/package-lock.json b/package-lock.json index ea9787b..a3f80fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,26 +1,27 @@ { "name": "@toruslabs/torus.js", - "version": "14.0.1", + "version": "15.0.0-alpha.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@toruslabs/torus.js", - "version": "14.0.1", + "version": "15.0.0-alpha.1", "license": "MIT", "dependencies": { "@toruslabs/constants": "^14.0.0", "@toruslabs/eccrypto": "^5.0.4", "@toruslabs/http-helpers": "^7.0.0", "bn.js": "^5.2.1", - "elliptic": "^6.5.5", + "bs58": "^6.0.0", + "elliptic": "^6.5.6", "ethereum-cryptography": "^2.2.1", "json-stable-stringify": "^1.1.1", "loglevel": "^1.9.1" }, "devDependencies": { "@babel/register": "^7.24.6", - "@babel/runtime": "^7.24.8", + "@babel/runtime": "^7.25.0", "@toruslabs/config": "^2.1.0", "@toruslabs/eslint-config-typescript": "^3.3.1", "@toruslabs/fetch-node-details": "^14.0.1", @@ -37,15 +38,15 @@ "dotenv": "^16.4.5", "eslint": "^8.57.0", "faker": "^5.5.3", - "husky": "^9.0.11", + "husky": "^9.1.4", "jsonwebtoken": "^9.0.2", "lint-staged": "^15.2.7", - "mocha": "^10.6.0", + "mocha": "^10.7.0", "prettier": "^3.3.3", "rimraf": "^6.0.1", "sinon": "^18.0.0", "ts-node": "^10.9.2", - "typescript": "^5.5.3" + "typescript": "^5.5.4" }, "engines": { "node": ">=18.x", @@ -1814,9 +1815,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", - "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -4203,15 +4204,14 @@ } }, "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "dependencies": { "bn.js": "^4.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" + "minimalistic-assert": "^1.0.0" } }, "node_modules/asn1.js/node_modules/bn.js": { @@ -4450,6 +4450,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base-x": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.0.tgz", + "integrity": "sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==" + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -4728,22 +4733,81 @@ } }, "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", + "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", "dev": true, "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", + "elliptic": "^6.5.5", + "hash-base": "~3.0", "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "parse-asn1": "^5.1.7", + "readable-stream": "^2.3.8", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/browserify-sign/node_modules/hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/browserify-sign/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, + "node_modules/browserify-sign/node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/browserify-sign/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/browserify-sign/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/browserify-zlib": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", @@ -4785,6 +4849,14 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bs58": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", + "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", + "dependencies": { + "base-x": "^5.0.0" + } + }, "node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", @@ -5323,6 +5395,12 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, "node_modules/cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", @@ -5810,9 +5888,9 @@ "dev": true }, "node_modules/elliptic": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz", - "integrity": "sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==", + "version": "6.5.6", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.6.tgz", + "integrity": "sha512-mpzdtpeCLuS3BmE3pO3Cpp5bbjlOPY2Q0PgoF+Od1XZrHLYI28Xe3ossCmYCQt11FQKEYd9+PF8jymTvtWJSHQ==", "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -7812,12 +7890,12 @@ } }, "node_modules/husky": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", - "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.4.tgz", + "integrity": "sha512-bho94YyReb4JV7LYWRWxZ/xr6TtOTt8cMfmQ39MQYJ7f/YE268s3GdghGwi+y4zAeqewE5zYLvuhV0M0ijsDEA==", "dev": true, "bin": { - "husky": "bin.mjs" + "husky": "bin.js" }, "engines": { "node": ">=18" @@ -9937,9 +10015,9 @@ } }, "node_modules/mocha": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.6.0.tgz", - "integrity": "sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.0.tgz", + "integrity": "sha512-v8/rBWr2VO5YkspYINnvu81inSz2y3ODJrhO175/Exzor1RcEZZkizgE2A+w/CAXXoESS8Kys5E62dOHGHzULA==", "dev": true, "dependencies": { "ansi-colors": "^4.1.3", @@ -10739,16 +10817,33 @@ } }, "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", + "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", "dev": true, "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "asn1.js": "^4.10.1", + "browserify-aes": "^1.2.0", + "evp_bytestokey": "^1.0.3", + "hash-base": "~3.0", + "pbkdf2": "^3.1.2", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse-asn1/node_modules/hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=4" } }, "node_modules/parse-json": { @@ -11048,6 +11143,12 @@ "node": ">= 0.6.0" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, "node_modules/proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", @@ -12924,9 +13025,9 @@ } }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 329b3ec..a408260 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@toruslabs/torus.js", - "version": "14.0.1", + "version": "15.0.0-alpha.1", "description": "Handle communication with torus nodes", "main": "dist/lib.cjs/index.js", "module": "dist/lib.esm/index.js", @@ -28,14 +28,15 @@ "@toruslabs/eccrypto": "^5.0.4", "@toruslabs/http-helpers": "^7.0.0", "bn.js": "^5.2.1", - "elliptic": "^6.5.5", + "elliptic": "^6.5.6", + "bs58": "^6.0.0", "ethereum-cryptography": "^2.2.1", "json-stable-stringify": "^1.1.1", "loglevel": "^1.9.1" }, "devDependencies": { "@babel/register": "^7.24.6", - "@babel/runtime": "^7.24.8", + "@babel/runtime": "^7.25.0", "@toruslabs/config": "^2.1.0", "@toruslabs/eslint-config-typescript": "^3.3.1", "@toruslabs/fetch-node-details": "^14.0.1", @@ -52,15 +53,15 @@ "dotenv": "^16.4.5", "eslint": "^8.57.0", "faker": "^5.5.3", - "husky": "^9.0.11", + "husky": "^9.1.4", "jsonwebtoken": "^9.0.2", "lint-staged": "^15.2.7", - "mocha": "^10.6.0", + "mocha": "^10.7.0", "prettier": "^3.3.3", "rimraf": "^6.0.1", "sinon": "^18.0.0", "ts-node": "^10.9.2", - "typescript": "^5.5.3" + "typescript": "^5.5.4" }, "repository": { "type": "git", diff --git a/src/Point.ts b/src/Point.ts index 8f8d91b..1c7f51f 100644 --- a/src/Point.ts +++ b/src/Point.ts @@ -19,7 +19,11 @@ class Point { encode(enc: string): Buffer { switch (enc) { case "arr": - return Buffer.concat([Buffer.from("04", "hex"), Buffer.from(this.x.toString("hex"), "hex"), Buffer.from(this.y.toString("hex"), "hex")]); + return Buffer.concat([ + Buffer.from("04", "hex"), + Buffer.from(this.x.toString("hex", 64), "hex"), + Buffer.from(this.y.toString("hex", 64), "hex"), + ]); case "elliptic-compressed": { const key = this.ecCurve.keyFromPublic({ x: this.x.toString("hex", 64), y: this.y.toString("hex", 64) }, "hex"); return Buffer.from(key.getPublic(true, "hex")); diff --git a/src/Polynomial.ts b/src/Polynomial.ts index b5237f7..c86ab4f 100644 --- a/src/Polynomial.ts +++ b/src/Polynomial.ts @@ -30,9 +30,9 @@ class Polynomial { for (let i = 1; i < this.polynomial.length; i += 1) { const tmp = xi.mul(this.polynomial[i]); sum = sum.add(tmp); - sum = sum.umod(this.ecCurve.curve.n); + sum = sum.umod(this.ecCurve.n); xi = xi.mul(new BN(tmpX)); - xi = xi.umod(this.ecCurve.curve.n); + xi = xi.umod(this.ecCurve.n); } return sum; } diff --git a/src/Share.ts b/src/Share.ts index 86df11f..a048949 100644 --- a/src/Share.ts +++ b/src/Share.ts @@ -19,8 +19,8 @@ class Share { toJSON(): StringifiedType { return { - share: this.share.toString("hex"), - shareIndex: this.shareIndex.toString("hex"), + share: this.share.toString("hex", 64), + shareIndex: this.shareIndex.toString("hex", 64), }; } } diff --git a/src/TorusUtilsExtraParams.ts b/src/TorusUtilsExtraParams.ts new file mode 100644 index 0000000..e9dc942 --- /dev/null +++ b/src/TorusUtilsExtraParams.ts @@ -0,0 +1,23 @@ +export interface TorusUtilsExtraParams { + nonce?: string; // farcaster + + message?: string; // farcaster + + signature?: string; // farcaster, passkey, webauthn + + clientDataJson?: string; // passkey, webauthn + + authenticatorData?: string; // passkey, webauhn + + publicKey?: string; // passkey, webauthn + + challenge?: string; // passkey, webauthn + + rpOrigin?: string; // passkey, webauthn + + rpId?: string; // passkey, webauthn + + session_token_exp_second?: number; + + timestamp?: number; // Signature +} diff --git a/src/constants.ts b/src/constants.ts index 51da688..c1019a4 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,7 +1,7 @@ export const JRPC_METHODS = { GET_OR_SET_KEY: "GetPubKeyOrKeyAssign", COMMITMENT_REQUEST: "CommitmentRequest", - IMPORT_SHARE: "ImportShare", + IMPORT_SHARES: "ImportShares", GET_SHARE_OR_KEY_ASSIGN: "GetShareOrKeyAssign", }; diff --git a/src/helpers/common.ts b/src/helpers/common.ts index 6d814a4..8d37f0a 100644 --- a/src/helpers/common.ts +++ b/src/helpers/common.ts @@ -1,9 +1,29 @@ -import { JRPCResponse } from "@toruslabs/constants"; +import { JRPCResponse, KEY_TYPE } from "@toruslabs/constants"; import { Ecies } from "@toruslabs/eccrypto"; +import { BN } from "bn.js"; +import { ec as EC } from "elliptic"; +import { keccak256 as keccakHash } from "ethereum-cryptography/keccak"; import JsonStringify from "json-stable-stringify"; -import { CommitmentRequestResult, EciesHex, VerifierLookupResponse } from "../interfaces"; +import { CommitmentRequestResult, EciesHex, KeyType, VerifierLookupResponse } from "../interfaces"; +export function keccak256(a: Buffer): string { + const hash = Buffer.from(keccakHash(a)).toString("hex"); + return `0x${hash}`; +} + +export const generatePrivateKey = (ecCurve: EC, buf: typeof Buffer): Buffer => { + return ecCurve.genKeyPair().getPrivate().toArrayLike(buf); +}; + +export const getKeyCurve = (keyType: KeyType) => { + if (keyType === KEY_TYPE.ED25519) { + return new EC(KEY_TYPE.ED25519); + } else if (keyType === KEY_TYPE.SECP256K1) { + return new EC(KEY_TYPE.SECP256K1); + } + throw new Error(`Invalid keyType: ${keyType}`); +}; // 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 created_at field might vary and nonce_data might not be returned by all nodes because @@ -86,6 +106,13 @@ export function encParamsHexToBuf(eciesData: Omit): Omit }; } +export function getProxyCoordinatorEndpointIndex(endpoints: string[], verifier: string, verifierId: string) { + const verifierIdStr = `${verifier}${verifierId}`; + const hashedVerifierId = keccak256(Buffer.from(verifierIdStr, "utf8")).slice(2); + const proxyEndpointNum = new BN(hashedVerifierId, "hex").mod(new BN(endpoints.length)).toNumber(); + return proxyEndpointNum; +} + export function calculateMedian(arr: number[]): number { const arrSize = arr.length; diff --git a/src/helpers/keyUtils.ts b/src/helpers/keyUtils.ts index cfd01af..12810c6 100644 --- a/src/helpers/keyUtils.ts +++ b/src/helpers/keyUtils.ts @@ -1,11 +1,17 @@ +import { INodePub, KEY_TYPE } from "@toruslabs/constants"; +import { Ecies, encrypt } from "@toruslabs/eccrypto"; import BN from "bn.js"; -import { ec } from "elliptic"; +import base58 from "bs58"; +import { curve, ec as EC } from "elliptic"; import { keccak256 as keccakHash } from "ethereum-cryptography/keccak"; +import { sha512 } from "ethereum-cryptography/sha512"; +import stringify from "json-stable-stringify"; +import log from "loglevel"; -export function keccak256(a: Buffer): string { - const hash = Buffer.from(keccakHash(a)).toString("hex"); - return `0x${hash}`; -} +import { EncryptedSeed, ImportedShare, KeyType, PrivateKeyData } from "../interfaces"; +import { encParamsBufToHex, generatePrivateKey, getKeyCurve, keccak256 } from "./common"; +import { generateRandomPolynomial } from "./langrangeInterpolatePoly"; +import { generateNonceMetadataParams, getSecpKeyFromEd25519 } from "./metadataUtils"; export function stripHexPrefix(str: string): string { return str.startsWith("0x") ? str.slice(2) : str; @@ -29,22 +35,201 @@ export function toChecksumAddress(hexAddress: string): string { return ret; } -export function generateAddressFromPrivKey(ecCurve: ec, privateKey: BN): string { +function adjustScalarBytes(bytes: Buffer): Buffer { + // Section 5: For X25519, in order to decode 32 random bytes as an integer scalar, + // set the three least significant bits of the first byte + bytes[0] &= 248; // 0b1111_1000 + // and the most significant bit of the last to zero, + bytes[31] &= 127; // 0b0111_1111 + // set the second most significant bit of the last byte to 1 + bytes[31] |= 64; // 0b0100_0000 + return bytes; +} + +/** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */ +export function getEd25519ExtendedPublicKey(keyBuffer: Buffer): { + scalar: BN; + point: curve.base.BasePoint; +} { + const ed25519Curve = getKeyCurve(KEY_TYPE.ED25519); + const len = 32; + const G = ed25519Curve.g; + const N = ed25519Curve.n; + + if (keyBuffer.length !== 32) { + log.error("Invalid seed for ed25519 key derivation", keyBuffer.length); + throw new Error("Invalid seed for ed25519 key derivation"); + } + // Hash private key with curve's hash function to produce uniformingly random input + // Check byte lengths: ensure(64, h(ensure(32, key))) + const hashed = sha512(keyBuffer); + if (hashed.length !== 64) { + throw new Error("Invalid hash length for ed25519 seed"); + } + const head = new BN(adjustScalarBytes(Buffer.from(hashed.slice(0, len))), "le"); + const scalar = new BN(head.umod(N), "le"); // The actual private scalar + const point = G.mul(scalar) as curve.base.BasePoint; // Point on Edwards curve aka public key + return { scalar, point }; +} + +export function encodeEd25519Point(point: curve.base.BasePoint) { + const ed25519Curve = getKeyCurve(KEY_TYPE.ED25519); + + const encodingLength = Math.ceil(ed25519Curve.n.bitLength() / 8); + const enc = point.getY().toArrayLike(Buffer, "le", encodingLength); + enc[encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0; + return enc; +} + +export const generateEd25519KeyData = async (ed25519Seed: Buffer): Promise => { + const ed25519Curve = getKeyCurve(KEY_TYPE.ED25519); + + const finalEd25519Key = getEd25519ExtendedPublicKey(ed25519Seed); + const encryptionKey = getSecpKeyFromEd25519(finalEd25519Key.scalar); + const encryptedSeed = await encrypt(Buffer.from(encryptionKey.point.encodeCompressed("hex"), "hex"), ed25519Seed); + const encData: EncryptedSeed = { + enc_text: encryptedSeed.ciphertext.toString("hex"), + metadata: encParamsBufToHex(encryptedSeed), + public_key: encodeEd25519Point(finalEd25519Key.point).toString("hex"), + }; + + const encDataBase64 = Buffer.from(JSON.stringify(encData), "utf-8").toString("base64"); + const metadataPrivNonce = ed25519Curve.genKeyPair().getPrivate(); + const oauthKey = finalEd25519Key.scalar.sub(metadataPrivNonce).umod(ed25519Curve.n); + const oauthKeyPair = ed25519Curve.keyFromPrivate(oauthKey.toArrayLike(Buffer)); + const metadataSigningKey = getSecpKeyFromEd25519(oauthKeyPair.getPrivate()); + return { + oAuthKeyScalar: oauthKeyPair.getPrivate(), + oAuthPubX: oauthKeyPair.getPublic().getX(), + oAuthPubY: oauthKeyPair.getPublic().getY(), + SigningPubX: metadataSigningKey.point.getX(), + SigningPubY: metadataSigningKey.point.getY(), + metadataNonce: metadataPrivNonce, + metadataSigningKey: metadataSigningKey.scalar, + encryptedSeed: encDataBase64, + finalUserPubKeyPoint: finalEd25519Key.point, + }; +}; + +export const generateSecp256k1KeyData = async (scalarBuffer: Buffer): Promise => { + const secp256k1Curve = getKeyCurve(KEY_TYPE.SECP256K1); + + const scalar = new BN(scalarBuffer); + const randomNonce = new BN(generatePrivateKey(secp256k1Curve, Buffer)); + const oAuthKey = scalar.sub(randomNonce).umod(secp256k1Curve.n); + const oAuthKeyPair = secp256k1Curve.keyFromPrivate(oAuthKey.toArrayLike(Buffer)); + const oAuthPubKey = oAuthKeyPair.getPublic(); + + const finalUserKeyPair = secp256k1Curve.keyFromPrivate(scalar.toString("hex", 64), "hex"); + + return { + oAuthKeyScalar: oAuthKeyPair.getPrivate(), + oAuthPubX: oAuthPubKey.getX(), + oAuthPubY: oAuthPubKey.getY(), + SigningPubX: oAuthPubKey.getX(), + SigningPubY: oAuthPubKey.getY(), + metadataNonce: randomNonce, + encryptedSeed: "", + metadataSigningKey: oAuthKeyPair.getPrivate(), + finalUserPubKeyPoint: finalUserKeyPair.getPublic(), + }; +}; + +function generateAddressFromEcKey(keyType: KeyType, key: EC.KeyPair): string { + if (keyType === KEY_TYPE.SECP256K1) { + const publicKey = key.getPublic().encode("hex", false).slice(2); + const evmAddressLower = `0x${keccak256(Buffer.from(publicKey, "hex")).slice(64 - 38)}`; + return toChecksumAddress(evmAddressLower); + } else if (keyType === KEY_TYPE.ED25519) { + const publicKey = encodeEd25519Point(key.getPublic()); + const address = base58.encode(publicKey); + return address; + } + throw new Error(`Invalid keyType: ${keyType}`); +} + +export function generateAddressFromPrivKey(keyType: KeyType, privateKey: BN): string { + const ecCurve = getKeyCurve(keyType); const key = ecCurve.keyFromPrivate(privateKey.toString("hex", 64), "hex"); - const publicKey = key.getPublic().encode("hex", false).slice(2); - const evmAddressLower = `0x${keccak256(Buffer.from(publicKey, "hex")).slice(64 - 38)}`; - return toChecksumAddress(evmAddressLower); + return generateAddressFromEcKey(keyType, key); } -export function generateAddressFromPubKey(ecCurve: ec, publicKeyX: BN, publicKeyY: BN): string { +export function generateAddressFromPubKey(keyType: KeyType, publicKeyX: BN, publicKeyY: BN): string { + const ecCurve = getKeyCurve(keyType); const key = ecCurve.keyFromPublic({ x: publicKeyX.toString("hex", 64), y: publicKeyY.toString("hex", 64) }); - const publicKey = key.getPublic().encode("hex", false).slice(2); - const evmAddressLower = `0x${keccak256(Buffer.from(publicKey, "hex")).slice(64 - 38)}`; - return toChecksumAddress(evmAddressLower); + return generateAddressFromEcKey(keyType, key); } -export function getPostboxKeyFrom1OutOf1(ecCurve: ec, privKey: string, nonce: string): string { +export function getPostboxKeyFrom1OutOf1(ecCurve: EC, privKey: string, nonce: string): string { const privKeyBN = new BN(privKey, 16); const nonceBN = new BN(nonce, 16); - return privKeyBN.sub(nonceBN).umod(ecCurve.curve.n).toString("hex"); + return privKeyBN.sub(nonceBN).umod(ecCurve.n).toString("hex"); +} + +export function derivePubKey(ecCurve: EC, sk: BN): curve.base.BasePoint { + const skHex = sk.toString(16, 64); + return ecCurve.keyFromPrivate(skHex, "hex").getPublic(); } + +export const getEncryptionEC = (): EC => { + return new EC("secp256k1"); +}; + +export const generateShares = async ( + ecCurve: EC, + keyType: KeyType, + serverTimeOffset: number, + nodeIndexes: number[], + nodePubkeys: INodePub[], + privKey: Buffer +) => { + const keyData = keyType === KEY_TYPE.ED25519 ? await generateEd25519KeyData(privKey) : await generateSecp256k1KeyData(privKey); + const { metadataNonce, oAuthKeyScalar: oAuthKey, encryptedSeed, metadataSigningKey } = keyData; + const threshold = ~~(nodePubkeys.length / 2) + 1; + const degree = threshold - 1; + const nodeIndexesBn: BN[] = []; + + for (const nodeIndex of nodeIndexes) { + nodeIndexesBn.push(new BN(nodeIndex)); + } + const oAuthPubKey = ecCurve.keyFromPrivate(oAuthKey.toString("hex", 64), "hex").getPublic(); + const poly = generateRandomPolynomial(ecCurve, degree, oAuthKey); + const shares = poly.generateShares(nodeIndexesBn); + const nonceParams = generateNonceMetadataParams(serverTimeOffset, "getOrSetNonce", metadataSigningKey, keyType, metadataNonce, encryptedSeed); + const nonceData = Buffer.from(stringify(nonceParams.set_data), "utf8").toString("base64"); + const sharesData: ImportedShare[] = []; + const encPromises: Promise[] = []; + for (let i = 0; i < nodeIndexesBn.length; i++) { + const shareJson = shares[nodeIndexesBn[i].toString("hex", 64)].toJSON() as Record; + if (!nodePubkeys[i]) { + throw new Error(`Missing node pub key for node index: ${nodeIndexesBn[i].toString("hex", 64)}`); + } + const nodePubKey = getEncryptionEC().keyFromPublic({ x: nodePubkeys[i].X, y: nodePubkeys[i].Y }); + encPromises.push( + encrypt(Buffer.from(nodePubKey.getPublic().encodeCompressed("hex"), "hex"), Buffer.from(shareJson.share.padStart(64, "0"), "hex")) + ); + } + const encShares = await Promise.all(encPromises); + for (let i = 0; i < nodeIndexesBn.length; i += 1) { + const shareJson = shares[nodeIndexesBn[i].toString("hex", 64)].toJSON() as Record; + const encParams = encShares[i]; + const encParamsMetadata = encParamsBufToHex(encParams); + const shareData: ImportedShare = { + encrypted_seed: keyData.encryptedSeed, + final_user_point: keyData.finalUserPubKeyPoint, + oauth_pub_key_x: oAuthPubKey.getX().toString("hex"), + oauth_pub_key_y: oAuthPubKey.getY().toString("hex"), + signing_pub_key_x: keyData.SigningPubX.toString("hex"), + signing_pub_key_y: keyData.SigningPubY.toString("hex"), + encrypted_share: encParamsMetadata.ciphertext, + encrypted_share_metadata: encParamsMetadata, + node_index: Number.parseInt(shareJson.shareIndex, 16), + key_type: keyType, + nonce_data: nonceData, + nonce_signature: nonceParams.signature, + }; + sharesData.push(shareData); + } + + return sharesData; +}; diff --git a/src/helpers/langrangeInterpolatePoly.ts b/src/helpers/langrangeInterpolatePoly.ts index c995996..568f342 100644 --- a/src/helpers/langrangeInterpolatePoly.ts +++ b/src/helpers/langrangeInterpolatePoly.ts @@ -1,15 +1,15 @@ -import { generatePrivate } from "@toruslabs/eccrypto"; import BN from "bn.js"; import { ec as EC } from "elliptic"; import Point from "../Point"; import Polynomial from "../Polynomial"; import Share from "../Share"; +import { generatePrivateKey } from "./common"; -function generatePrivateExcludingIndexes(shareIndexes: BN[]): BN { - const key = new BN(generatePrivate()); +function generatePrivateExcludingIndexes(shareIndexes: BN[], ecCurve: EC): BN { + const key = new BN(generatePrivateKey(ecCurve, Buffer)); if (shareIndexes.find((el) => el.eq(key))) { - return generatePrivateExcludingIndexes(shareIndexes); + return generatePrivateExcludingIndexes(shareIndexes, ecCurve); } return key; } @@ -22,9 +22,9 @@ const denominator = (ecCurve: EC, i: number, innerPoints: Point[]) => { if (i !== j) { let tmp = new BN(xi); tmp = tmp.sub(innerPoints[j].x); - tmp = tmp.umod(ecCurve.curve.n); + tmp = tmp.umod(ecCurve.n); result = result.mul(tmp); - result = result.umod(ecCurve.curve.n); + result = result.umod(ecCurve.n); } } return result; @@ -36,7 +36,7 @@ const interpolationPoly = (ecCurve: EC, i: number, innerPoints: Point[]): BN[] = if (d.cmp(new BN(0)) === 0) { throw new Error("Denominator for interpolationPoly is 0"); } - coefficients[0] = d.invm(ecCurve.curve.n); + coefficients[0] = d.invm(ecCurve.n); for (let k = 0; k < innerPoints.length; k += 1) { const newCoefficients = generateEmptyBNArray(innerPoints.length); if (k !== i) { @@ -48,10 +48,10 @@ const interpolationPoly = (ecCurve: EC, i: number, innerPoints: Point[]): BN[] = } j -= 1; for (; j >= 0; j -= 1) { - newCoefficients[j + 1] = newCoefficients[j + 1].add(coefficients[j]).umod(ecCurve.curve.n); + newCoefficients[j + 1] = newCoefficients[j + 1].add(coefficients[j]).umod(ecCurve.n); let tmp = new BN(innerPoints[k].x); - tmp = tmp.mul(coefficients[j]).umod(ecCurve.curve.n); - newCoefficients[j] = newCoefficients[j].sub(tmp).umod(ecCurve.curve.n); + tmp = tmp.mul(coefficients[j]).umod(ecCurve.n); + newCoefficients[j] = newCoefficients[j].sub(tmp).umod(ecCurve.n); } coefficients = newCoefficients; } @@ -73,7 +73,7 @@ const lagrange = (ecCurve: EC, unsortedPoints: Point[]) => { for (let k = 0; k < sortedPoints.length; k += 1) { let tmp = new BN(sortedPoints[i].y); tmp = tmp.mul(coefficients[k]); - polynomial[k] = polynomial[k].add(tmp).umod(ecCurve.curve.n); + polynomial[k] = polynomial[k].add(tmp).umod(ecCurve.n); } } return new Polynomial(polynomial, ecCurve); @@ -94,29 +94,29 @@ export function lagrangeInterpolation(ecCurve: EC, shares: BN[], nodeIndex: BN[] for (let j = 0; j < shares.length; j += 1) { if (i !== j) { upper = upper.mul(nodeIndex[j].neg()); - upper = upper.umod(ecCurve.curve.n); + upper = upper.umod(ecCurve.n); let temp = nodeIndex[i].sub(nodeIndex[j]); - temp = temp.umod(ecCurve.curve.n); - lower = lower.mul(temp).umod(ecCurve.curve.n); + temp = temp.umod(ecCurve.n); + lower = lower.mul(temp).umod(ecCurve.n); } } - let delta = upper.mul(lower.invm(ecCurve.curve.n)).umod(ecCurve.curve.n); - delta = delta.mul(shares[i]).umod(ecCurve.curve.n); + let delta = upper.mul(lower.invm(ecCurve.n)).umod(ecCurve.n); + delta = delta.mul(shares[i]).umod(ecCurve.n); secret = secret.add(delta); } - return secret.umod(ecCurve.curve.n); + return secret.umod(ecCurve.n); } // generateRandomPolynomial - determinisiticShares are assumed random export function generateRandomPolynomial(ecCurve: EC, degree: number, secret?: BN, deterministicShares?: Share[]): Polynomial { let actualS = secret; if (!secret) { - actualS = generatePrivateExcludingIndexes([new BN(0)]); + actualS = generatePrivateExcludingIndexes([new BN(0)], ecCurve); } if (!deterministicShares) { const poly = [actualS]; for (let i = 0; i < degree; i += 1) { - const share = generatePrivateExcludingIndexes(poly); + const share = generatePrivateExcludingIndexes(poly, ecCurve); poly.push(share); } return new Polynomial(poly, ecCurve); @@ -133,11 +133,11 @@ export function generateRandomPolynomial(ecCurve: EC, degree: number, secret?: B points[share.shareIndex.toString("hex", 64)] = new Point(share.shareIndex, share.share, ecCurve); }); for (let i = 0; i < degree - deterministicShares.length; i += 1) { - let shareIndex = generatePrivateExcludingIndexes([new BN(0)]); + let shareIndex = generatePrivateExcludingIndexes([new BN(0)], ecCurve); while (points[shareIndex.toString("hex", 64)] !== undefined) { - shareIndex = generatePrivateExcludingIndexes([new BN(0)]); + shareIndex = generatePrivateExcludingIndexes([new BN(0)], ecCurve); } - points[shareIndex.toString("hex", 64)] = new Point(shareIndex, new BN(generatePrivate()), ecCurve); + points[shareIndex.toString("hex", 64)] = new Point(shareIndex, new BN(generatePrivateKey(ecCurve, Buffer)), ecCurve); } points["0"] = new Point(new BN(0), actualS, ecCurve); return lagrangeInterpolatePolynomial(ecCurve, Object.values(points)); diff --git a/src/helpers/metadataUtils.ts b/src/helpers/metadataUtils.ts index 3ffb9e6..ed992c1 100644 --- a/src/helpers/metadataUtils.ts +++ b/src/helpers/metadataUtils.ts @@ -1,17 +1,49 @@ -import { LEGACY_NETWORKS_ROUTE_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE, TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; +import { KEY_TYPE, LEGACY_NETWORKS_ROUTE_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE, TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; import { decrypt } from "@toruslabs/eccrypto"; import { Data, post } from "@toruslabs/http-helpers"; import BN from "bn.js"; -import { ec as EC } from "elliptic"; +import { curve, ec as EC } from "elliptic"; +import { keccak256 as keccakHash } from "ethereum-cryptography/keccak"; import stringify from "json-stable-stringify"; import log from "loglevel"; import { SAPPHIRE_DEVNET_METADATA_URL, SAPPHIRE_METADATA_URL } from "../constants"; -import { EciesHex, GetOrSetNonceResult, MetadataParams, SapphireMetadataParams } from "../interfaces"; -import { encParamsHexToBuf } from "./common"; -import { keccak256 } from "./keyUtils"; +import { + EciesHex, + EncryptedSeed, + GetOrSetNonceResult, + KeyType, + MetadataParams, + NonceMetadataParams, + SapphireMetadataParams, + SetNonceData, +} from "../interfaces"; +import { encParamsHexToBuf, getKeyCurve, keccak256 } from "./common"; + +export const getSecpKeyFromEd25519 = ( + ed25519Scalar: BN +): { + scalar: BN; + point: curve.base.BasePoint; +} => { + const secp256k1Curve = getKeyCurve(KEY_TYPE.SECP256K1); + + const ed25519Key = ed25519Scalar.toString("hex", 64); + const keyHash = keccakHash(Buffer.from(ed25519Key, "hex")); + const secpKey = new BN(keyHash).umod(secp256k1Curve.n).toString("hex", 64); + const bufferKey = Buffer.from(secpKey, "hex"); + + const secpKeyPair = secp256k1Curve.keyFromPrivate(bufferKey); + + if (bufferKey.length < 32) { + throw new Error(`Key length must be less than 32. got ${bufferKey.length}`); + } + return { + scalar: secpKeyPair.getPrivate(), + point: secpKeyPair.getPublic(), + }; +}; -const secp256k1Curve = new EC("secp256k1"); export function convertMetadataToNonce(params: { message?: string }) { if (!params || !params.message) { return new BN(0); @@ -28,8 +60,26 @@ export async function decryptNodeData(eciesData: EciesHex, ciphertextHex: string return decryptedSigBuffer; } +export async function decryptNodeDataWithPadding(eciesData: EciesHex, ciphertextHex: string, privKey: Buffer): Promise { + const metadata = encParamsHexToBuf(eciesData); + try { + const decryptedSigBuffer = await decrypt(privKey, { + ...metadata, + ciphertext: Buffer.from(ciphertextHex, "hex"), + }); + return decryptedSigBuffer; + } catch (error) { + // ciphertext can be any length. not just 64. depends on input. we have this for legacy reason + const ciphertextHexPadding = ciphertextHex.padStart(64, "0"); + + log.warn("Failed to decrypt padded share cipher", error); + // try without cipher text padding + return decrypt(privKey, { ...metadata, ciphertext: Buffer.from(ciphertextHexPadding, "hex") }); + } +} + export function generateMetadataParams(ecCurve: EC, serverTimeOffset: number, message: string, privateKey: BN): MetadataParams { - const key = ecCurve.keyFromPrivate(privateKey.toString("hex", 64)); + const key = ecCurve.keyFromPrivate(privateKey.toString("hex", 64), "hex"); const setData = { data: message, timestamp: new BN(~~(serverTimeOffset + Date.now() / 1000)).toString(16), @@ -60,29 +110,94 @@ export async function getMetadata( } } +export function generateNonceMetadataParams( + serverTimeOffset: number, + operation: string, + privateKey: BN, + keyType: KeyType, + nonce?: BN, + seed?: string +): NonceMetadataParams { + // metadata only uses secp for sig validation + const key = getKeyCurve(KEY_TYPE.SECP256K1).keyFromPrivate(privateKey.toString("hex", 64), "hex"); + const setData: Partial = { + operation, + timestamp: new BN(~~(serverTimeOffset + Date.now() / 1000)).toString(16), + }; + + if (nonce) { + setData.data = nonce.toString("hex", 64); + } + + if (seed) { + setData.seed = seed; + } else { + setData.seed = ""; // setting it as empty to keep ordering same while serializing the data on backend. + } + + const sig = key.sign(keccak256(Buffer.from(stringify(setData), "utf8")).slice(2)); + return { + pub_key_X: key.getPublic().getX().toString("hex", 64), + pub_key_Y: key.getPublic().getY().toString("hex", 64), + set_data: setData, + key_type: keyType, + signature: Buffer.from(sig.r.toString(16, 64) + sig.s.toString(16, 64) + new BN("").toString(16, 2), "hex").toString("base64"), + }; +} + export async function getOrSetNonce( - legacyMetadataHost: string, + metadataHost: string, ecCurve: EC, serverTimeOffset: number, X: string, Y: string, privKey?: BN, - getOnly = false + getOnly = false, + isLegacyMetadata = true, + nonce = new BN(0), + keyType: KeyType = "secp256k1", + seed = "" ): Promise { - let data: Data; - const msg = getOnly ? "getNonce" : "getOrSetNonce"; - if (privKey) { - data = generateMetadataParams(ecCurve, serverTimeOffset, msg, privKey); - } else { - data = { - pub_key_X: X, - pub_key_Y: Y, - set_data: { data: msg }, - }; + // for legacy metadata + if (isLegacyMetadata) { + let data: Data; + const msg = getOnly ? "getNonce" : "getOrSetNonce"; + if (privKey) { + data = generateMetadataParams(ecCurve, serverTimeOffset, msg, privKey); + } else { + data = { + pub_key_X: X, + pub_key_Y: Y, + set_data: { data: msg }, + }; + } + return post(`${metadataHost}/get_or_set_nonce`, data, undefined, { useAPIKey: true }); } - return post(`${legacyMetadataHost}/get_or_set_nonce`, data, undefined, { useAPIKey: true }); -} + // for sapphire metadata + const operation = getOnly ? "getNonce" : "getOrSetNonce"; + if (operation === "getOrSetNonce") { + if (!privKey) { + throw new Error("privKey is required while `getOrSetNonce` for non legacy metadata"); + } + if (nonce.cmp(new BN(0)) === 0) { + throw new Error("nonce is required while `getOrSetNonce` for non legacy metadata"); + } + if (keyType === KEY_TYPE.ED25519 && !seed) { + throw new Error("seed is required while `getOrSetNonce` for non legacy metadata for ed25519 key type"); + } + const data = generateNonceMetadataParams(serverTimeOffset, operation, privKey, keyType, nonce, seed); + + return post(`${metadataHost}/get_or_set_nonce`, data, undefined, { useAPIKey: true }); + } + const data = { + pub_key_X: X, + pub_key_Y: Y, + set_data: { operation }, + key_type: keyType, + }; + return post(`${metadataHost}/get_or_set_nonce`, data, undefined, { useAPIKey: true }); +} export async function getNonce( legacyMetadataHost: string, ecCurve: EC, @@ -93,6 +208,21 @@ export async function getNonce( ): Promise { return getOrSetNonce(legacyMetadataHost, ecCurve, serverTimeOffset, X, Y, privKey, true); } + +export const decryptSeedData = async (seedBase64: string, finalUserKey: BN) => { + const decryptionKey = getSecpKeyFromEd25519(finalUserKey); + const seedUtf8 = Buffer.from(seedBase64, "base64").toString("utf-8"); + const seedJson = JSON.parse(seedUtf8) as EncryptedSeed; + const bufferMetadata = { ...encParamsHexToBuf(seedJson.metadata), mode: "AES256" }; + const bufferKey = decryptionKey.scalar.toArrayLike(Buffer); + const decText = await decrypt(bufferKey, { + ...bufferMetadata, + ciphertext: Buffer.from(seedJson.enc_text, "hex"), + }); + + return decText; +}; + export async function getOrSetSapphireMetadataNonce( network: TORUS_NETWORK_TYPE, X: string, @@ -110,7 +240,7 @@ export async function getOrSetSapphireMetadataNonce( set_data: { operation: "getOrSetNonce" }, }; if (privKey) { - const key = secp256k1Curve.keyFromPrivate(privKey.toString("hex", 64)); + const key = getKeyCurve(KEY_TYPE.SECP256K1).keyFromPrivate(privKey.toString("hex", 64), "hex"); const setData = { operation: "getOrSetNonce", diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 20ba121..ffc7cc3 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -1,18 +1,21 @@ -import { LEGACY_NETWORKS_ROUTE_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE } from "@toruslabs/constants"; +import { INodePub, KEY_TYPE, LEGACY_NETWORKS_ROUTE_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE } from "@toruslabs/constants"; import { generatePrivate, getPublic } from "@toruslabs/eccrypto"; import { generateJsonRPCObject, get, post } from "@toruslabs/http-helpers"; import BN from "bn.js"; import { curve, ec } from "elliptic"; +import { getRandomBytes } from "ethereum-cryptography/random"; import { config } from "../config"; import { JRPC_METHODS } from "../constants"; import { CommitmentRequestResult, + ExtendedPublicKey, GetOrSetNonceResult, ImportedShare, ImportShareRequestResult, JRPCResponse, KeyLookupResult, + KeyType, SessionToken, ShareRequestResult, TorusKey, @@ -23,19 +26,38 @@ import { } from "../interfaces"; import log from "../loglevel"; import { Some } from "../some"; -import { calculateMedian, kCombinations, normalizeKeysResult, retryCommitment, thresholdSame } from "./common"; -import { generateAddressFromPrivKey, generateAddressFromPubKey, keccak256 } from "./keyUtils"; +import { TorusUtilsExtraParams } from "../TorusUtilsExtraParams"; +import { + calculateMedian, + generatePrivateKey, + getProxyCoordinatorEndpointIndex, + kCombinations, + keccak256, + normalizeKeysResult, + retryCommitment, + thresholdSame, +} from "./common"; +import { derivePubKey, generateAddressFromPrivKey, generateAddressFromPubKey, generateShares } from "./keyUtils"; import { lagrangeInterpolation } from "./langrangeInterpolatePoly"; -import { decryptNodeData, getMetadata, getOrSetNonce, getOrSetSapphireMetadataNonce } from "./metadataUtils"; +import { + decryptNodeData, + decryptNodeDataWithPadding, + decryptSeedData, + getMetadata, + getOrSetNonce, + getOrSetSapphireMetadataNonce, + getSecpKeyFromEd25519, +} from "./metadataUtils"; export const GetPubKeyOrKeyAssign = async (params: { endpoints: string[]; network: TORUS_NETWORK_TYPE; verifier: string; verifierId: string; + keyType: KeyType; extendedVerifierId?: string; }): Promise => { - const { endpoints, network, verifier, verifierId, extendedVerifierId } = params; + const { endpoints, network, verifier, verifierId, extendedVerifierId, keyType } = params; const minThreshold = ~~(endpoints.length / 2) + 1; const lookupPromises = endpoints.map((x) => post>( @@ -46,6 +68,7 @@ export const GetPubKeyOrKeyAssign = async (params: { verifier_id: verifierId.toString(), extended_verifier_id: extendedVerifierId, one_key_flow: true, + key_type: keyType, fetch_node_index: true, client_time: Math.floor(Date.now() / 1000).toString(), }), @@ -136,39 +159,46 @@ export const GetPubKeyOrKeyAssign = async (params: { return result; }; - export async function retrieveOrImportShare(params: { legacyMetadataHost: string; serverTimeOffset: number; enableOneKey: boolean; ecCurve: ec; + keyType: KeyType; allowHost: string; network: TORUS_NETWORK_TYPE; clientId: string; endpoints: string[]; + indexes: number[]; verifier: string; verifierParams: VerifierParams; idToken: string; - importedShares?: ImportedShare[]; - extraParams: Record; - indexes: number[]; + useDkg: boolean; + overrideExistingKey: boolean; + nodePubkeys: INodePub[]; + newImportedShares?: ImportedShare[]; + extraParams: TorusUtilsExtraParams; }): Promise { const { legacyMetadataHost, enableOneKey, ecCurve, + keyType, allowHost, network, clientId, endpoints, + nodePubkeys, + indexes, verifier, verifierParams, idToken, - importedShares, + overrideExistingKey, + newImportedShares, extraParams, + useDkg = true, serverTimeOffset, } = params; - const minThreshold = ~~(endpoints.length / 2) + 1; await get( allowHost, { @@ -189,15 +219,24 @@ export async function retrieveOrImportShare(params: { const pubKey = getPublic(sessionAuthKey).toString("hex"); const pubKeyX = pubKey.slice(2, 66); const pubKeyY = pubKey.slice(66); - const tokenCommitment = keccak256(Buffer.from(idToken, "utf8")); - let isImportShareReq = false; - if (importedShares && importedShares.length > 0) { - if (importedShares.length !== endpoints.length) { + let finalImportedShares: ImportedShare[] = []; + const threeFourthsThreshold = ~~((endpoints.length * 3) / 4) + 1; + const halfThreshold = ~~(endpoints.length / 2) + 1; + + if (newImportedShares?.length > 0) { + if (newImportedShares.length !== endpoints.length) { throw new Error("Invalid imported shares length"); } - isImportShareReq = true; + finalImportedShares = newImportedShares; + } else if (!useDkg) { + // TODO: why use getrandombytes here? + const bufferKey = keyType === KEY_TYPE.SECP256K1 ? generatePrivateKey(ecCurve, Buffer) : await getRandomBytes(32); + const generatedShares = await generateShares(ecCurve, keyType, serverTimeOffset, indexes, nodePubkeys, Buffer.from(bufferKey)); + finalImportedShares = [...finalImportedShares, ...generatedShares]; } + const tokenCommitment = keccak256(Buffer.from(idToken, "utf8")); + // make commitment requests to endpoints for (let i = 0; i < endpoints.length; i += 1) { /* @@ -214,10 +253,14 @@ export async function retrieveOrImportShare(params: { endpoints[i], generateJsonRPCObject(JRPC_METHODS.COMMITMENT_REQUEST, { messageprefix: "mug00", + keytype: keyType, tokencommitment: tokenCommitment.slice(2), temppubx: pubKeyX, temppuby: pubKeyY, verifieridentifier: verifier, + verifier_id: verifierParams.verifier_id, + extended_verifier_id: verifierParams.extended_verifier_id, + is_import_key_flow: true, }), {}, { logTracingHeader: config.logRequestTracing } @@ -237,17 +280,60 @@ export async function retrieveOrImportShare(params: { return true; }); - // we need to get commitments from all endpoints for importing share - if (importedShares?.length > 0 && completedRequests.length === endpoints.length) { - return Promise.resolve(resultArr); - } else if (importedShares?.length === 0 && completedRequests.length >= ~~((endpoints.length * 3) / 4) + 1) { + if (finalImportedShares.length > 0) { + // this is a optimization is for imported keys + // for new imported keys registration we need to wait for all nodes to agree on commitment + // for fetching existing imported keys we can rely on threshold nodes commitment + if (overrideExistingKey && completedRequests.length === endpoints.length) { + const requiredNodeResult = completedRequests.find((resp: void | JRPCResponse) => { + if (resp) { + return true; + } + return false; + }); + if (requiredNodeResult) { + return Promise.resolve(resultArr); + } + } else if (!overrideExistingKey && completedRequests.length >= threeFourthsThreshold) { + const nodeSigs: CommitmentRequestResult[] = []; + for (let i = 0; i < completedRequests.length; i += 1) { + const x = completedRequests[i]; + if (!x || typeof x !== "object" || x.error) { + continue; + } + if (x) nodeSigs.push((x as JRPCResponse).result); + } + const existingPubKey = thresholdSame( + nodeSigs.map((x) => x && x.pub_key_x), + halfThreshold + ); + const proxyEndpointNum = getProxyCoordinatorEndpointIndex(endpoints, verifier, verifierParams.verifier_id); + // for import shares, proxy node response is required. + // proxy node returns metadata. + // if user's account already + const requiredNodeIndex = indexes[proxyEndpointNum].toString(10); + + // if not a existing key we need to wait for nodes to agree on commitment + if (existingPubKey || (!existingPubKey && completedRequests.length === endpoints.length)) { + const requiredNodeResult = completedRequests.find((resp: void | JRPCResponse) => { + if (resp && resp.result?.nodeindex === requiredNodeIndex) { + return true; + } + return false; + }); + if (requiredNodeResult) { + return Promise.resolve(resultArr); + } + } + } + } else if (completedRequests.length >= threeFourthsThreshold) { + // this case is for dkg keys const requiredNodeResult = completedRequests.find((resp: void | JRPCResponse) => { if (resp) { return true; } return false; }); - if (requiredNodeResult) { return Promise.resolve(resultArr); } @@ -256,69 +342,83 @@ export async function retrieveOrImportShare(params: { return Promise.reject(new Error(`invalid commitment results ${JSON.stringify(resultArr)}`)); }) .then((responses) => { - const promiseArrRequest: Promise>[] = []; + const promiseArrRequest: Promise | JRPCResponse>[] = []; const nodeSigs: CommitmentRequestResult[] = []; for (let i = 0; i < responses.length; i += 1) { const x = responses[i]; - if (!x || typeof x !== "object") { - continue; - } - if (x.error) { + if (!x || typeof x !== "object" || x.error) { continue; } if (x) nodeSigs.push((x as JRPCResponse).result); } - for (let i = 0; i < endpoints.length; i += 1) { - const x = responses[i]; - if (!x || typeof x !== "object") { - continue; - } - if (x.error) { - continue; + + // if user's account already + const existingPubKey = thresholdSame( + nodeSigs.map((x) => x && x.pub_key_x), + halfThreshold + ); + + // can only import shares if override existing key is allowed or for new non dkg registration + const canImportedShares = overrideExistingKey || (!useDkg && !existingPubKey); + if (canImportedShares) { + const proxyEndpointNum = getProxyCoordinatorEndpointIndex(endpoints, verifier, verifierParams.verifier_id); + const items: Record[] = []; + for (let i = 0; i < endpoints.length; i += 1) { + const x = responses[i]; + if (!x || typeof x !== "object" || x.error) { + continue; + } + const importedShare = finalImportedShares[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, + }); } - if (isImportShareReq) { - const importedShare = importedShares[i]; - const p = post>( - endpoints[i], - generateJsonRPCObject(JRPC_METHODS.IMPORT_SHARE, { - encrypted: "yes", - use_temp: true, - distributed_metadata: true, - item: [ - { - ...verifierParams, - idtoken: idToken, - nodesignatures: nodeSigs, - verifieridentifier: verifier, - pub_key_x: importedShare.pub_key_x, - pub_key_y: importedShare.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, - ...extraParams, - }, - ], - one_key_flow: true, - client_time: Math.floor(Date.now() / 1000).toString(), - }), - {}, - { logTracingHeader: config.logRequestTracing } - ); - promiseArrRequest.push(p); - } else { + const p = post>( + endpoints[proxyEndpointNum], + generateJsonRPCObject(JRPC_METHODS.IMPORT_SHARES, { + encrypted: "yes", + use_temp: true, + item: items, + key_type: keyType, + one_key_flow: true, + }), + {}, + { logTracingHeader: config.logRequestTracing } + ).catch((err) => log.error("share req", err)); + promiseArrRequest.push(p); + } else { + for (let i = 0; i < endpoints.length; i += 1) { + const x = responses[i]; + if (!x || typeof x !== "object" || x.error) { + continue; + } const p = post>( endpoints[i], generateJsonRPCObject(JRPC_METHODS.GET_SHARE_OR_KEY_ASSIGN, { encrypted: "yes", use_temp: true, + key_type: keyType, distributed_metadata: true, item: [ { ...verifierParams, idtoken: idToken, + key_type: keyType, nodesignatures: nodeSigs, verifieridentifier: verifier, ...extraParams, @@ -335,21 +435,34 @@ export async function retrieveOrImportShare(params: { } let thresholdNonceData: GetOrSetNonceResult; return Some< - void | JRPCResponse, + void | JRPCResponse | JRPCResponse, | { privateKey: BN; - thresholdPublicKey: { - X: string; - Y: string; - }; sessionTokenData: SessionToken[]; thresholdNonceData: GetOrSetNonceResult; + thresholdPubKey: ExtendedPublicKey; nodeIndexes: BN[]; isNewKey: boolean; serverTimeOffsetResponse?: number; } | undefined - >(promiseArrRequest, async (shareResponses, sharedState) => { + >(promiseArrRequest, async (shareResponseResult, sharedState) => { + let shareResponses: (void | JRPCResponse)[] = []; + // for import shares case, where result is an array + if (shareResponseResult.length === 1 && shareResponseResult[0] && Array.isArray(shareResponseResult[0].result)) { + // this is for import shares + const importedSharesResult = shareResponseResult[0]; + shareResponseResult[0].result.forEach((res) => { + shareResponses.push({ + id: importedSharesResult.id, + jsonrpc: "2.0", + result: res, + error: importedSharesResult.error, + }); + }); + } else { + shareResponses = shareResponseResult as (void | JRPCResponse)[]; + } // check if threshold number of nodes have returned the same user public key const completedRequests = shareResponses.filter((x) => { if (!x || typeof x !== "object") { @@ -367,7 +480,7 @@ export async function retrieveOrImportShare(params: { return undefined; }); - const thresholdPublicKey = thresholdSame(pubkeys, minThreshold); + const thresholdPublicKey = thresholdSame(pubkeys, halfThreshold); if (!thresholdPublicKey) { throw new Error("invalid result from nodes, threshold number of public key results are not matching"); @@ -384,7 +497,7 @@ export async function retrieveOrImportShare(params: { } }); - const thresholdReqCount = importedShares.length > 0 ? endpoints.length : minThreshold; + const thresholdReqCount = canImportedShares ? 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 @@ -445,12 +558,11 @@ export async function retrieveOrImportShare(params: { if (keys?.length > 0) { const latestKey = currentShareResponse.result.keys[0]; nodeIndexes.push(new BN(latestKey.node_index)); - if (latestKey.share_metadata) { sharePromises.push( - decryptNodeData( + decryptNodeDataWithPadding( latestKey.share_metadata, - Buffer.from(latestKey.share, "base64").toString("binary").padStart(64, "0"), + Buffer.from(latestKey.share, "base64").toString("binary"), sessionAuthKey ).catch((err) => log.error("share decryption", err)) ); @@ -471,8 +583,8 @@ export async function retrieveOrImportShare(params: { return false; }); - if (!verifierParams.extended_verifier_id && validSigs.length < minThreshold) { - throw new Error(`Insufficient number of signatures from nodes, required: ${minThreshold}, found: ${validSigs.length}`); + if (!verifierParams.extended_verifier_id && validSigs.length < halfThreshold) { + throw new Error(`Insufficient number of signatures from nodes, required: ${halfThreshold}, found: ${validSigs.length}`); } const validTokens = sessionTokensResolved.filter((token) => { @@ -482,8 +594,8 @@ export async function retrieveOrImportShare(params: { return false; }); - if (!verifierParams.extended_verifier_id && validTokens.length < minThreshold) { - throw new Error(`Insufficient number of session tokens from nodes, required: ${minThreshold}, found: ${validTokens.length}`); + if (!verifierParams.extended_verifier_id && validTokens.length < halfThreshold) { + throw new Error(`Insufficient number of session tokens from nodes, required: ${halfThreshold}, found: ${validTokens.length}`); } sessionTokensResolved.forEach((x, index) => { if (!x || !sessionSigsResolved[index]) sessionTokenData.push(undefined); @@ -500,13 +612,15 @@ export async function retrieveOrImportShare(params: { const decryptedShares = sharesResolved.reduce( (acc, curr, index) => { - if (curr) acc.push({ index: nodeIndexes[index], value: new BN(curr) }); + 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, minThreshold); + const allCombis = kCombinations(decryptedShares.length, halfThreshold); let privateKey: BN | null = null; for (let j = 0; j < allCombis.length; j += 1) { @@ -516,13 +630,11 @@ export async function retrieveOrImportShare(params: { const indices = currentCombiShares.map((x) => x.index); const derivedPrivateKey = lagrangeInterpolation(ecCurve, 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 - ) { + const decryptedPubKey = derivePubKey(ecCurve, derivedPrivateKey); + const decryptedPubKeyX = decryptedPubKey.getX(); + const decryptedPubKeyY = decryptedPubKey.getY(); + + if (decryptedPubKeyX.cmp(new BN(thresholdPublicKey.X, 16)) === 0 && decryptedPubKeyY.cmp(new BN(thresholdPublicKey.Y, 16)) === 0) { privateKey = derivedPrivateKey; break; } @@ -531,22 +643,22 @@ export async function retrieveOrImportShare(params: { if (privateKey === undefined || privateKey === null) { throw new Error("could not derive private key"); } - const thresholdIsNewKey = thresholdSame(isNewKeyResponses, minThreshold); + + const thresholdIsNewKey = thresholdSame(isNewKeyResponses, halfThreshold); // Convert each string timestamp to a number const serverOffsetTimes = serverTimeOffsetResponses.map((timestamp) => Number.parseInt(timestamp, 10)); return { privateKey, - thresholdPublicKey, sessionTokenData, thresholdNonceData, nodeIndexes, + thresholdPubKey: thresholdPublicKey, isNewKey: thresholdIsNewKey === "true", serverTimeOffsetResponse: serverTimeOffset || calculateMedian(serverOffsetTimes), }; } - if (completedRequests.length < thresholdReqCount) { throw new Error(`Waiting for results from more nodes, pending: ${thresholdReqCount - completedRequests.length}`); } @@ -556,26 +668,20 @@ export async function retrieveOrImportShare(params: { }); }) .then(async (res) => { - const { privateKey, thresholdPublicKey, sessionTokenData, nodeIndexes, thresholdNonceData, isNewKey, serverTimeOffsetResponse } = res; + const { privateKey, thresholdPubKey, sessionTokenData, nodeIndexes, thresholdNonceData, isNewKey, serverTimeOffsetResponse } = res; let nonceResult = thresholdNonceData; if (!privateKey) throw new Error("Invalid private key returned"); const oAuthKey = privateKey; - const oAuthPubKey = getPublic(Buffer.from(oAuthKey.toString(16, 64), "hex")).toString("hex"); - const oAuthPubkeyX = oAuthPubKey.slice(2, 66); - const oAuthPubkeyY = oAuthPubKey.slice(66); + const oAuthPubKey = derivePubKey(ecCurve, oAuthKey); + const oAuthPubkeyX = oAuthPubKey.getX().toString("hex", 64); + const oAuthPubkeyY = oAuthPubKey.getY().toString("hex", 64); // if both thresholdNonceData and extended_verifier_id are not available // then we need to throw other wise address would be incorrect. if (!nonceResult && !verifierParams.extended_verifier_id && !LEGACY_NETWORKS_ROUTE_MAP[network as TORUS_LEGACY_NETWORK_TYPE]) { // NOTE: dont use padded pub key anywhere in metadata apis, send pub keys as is received from nodes. - const metadataNonceResult = await getOrSetSapphireMetadataNonce( - network, - thresholdPublicKey.X, - thresholdPublicKey.Y, - serverTimeOffset, - oAuthKey - ); + const metadataNonceResult = await getOrSetSapphireMetadataNonce(network, thresholdPubKey.X, thresholdPubKey.Y, serverTimeOffset, oAuthKey); // rechecking nonceResult to avoid promise race condition. if (metadataNonceResult && !thresholdNonceData) { nonceResult = metadataNonceResult; @@ -614,14 +720,14 @@ export async function retrieveOrImportShare(params: { typeOfUser = "v1"; // for imported keys in legacy networks metadataNonce = await getMetadata(legacyMetadataHost, { pub_key_X: oAuthPubkeyX, pub_key_Y: oAuthPubkeyY }); - const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.curve.n); + const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.n); finalPubKey = ecCurve.keyFromPrivate(privateKeyWithNonce.toString(16, 64), "hex").getPublic(); } } else { typeOfUser = "v1"; // for imported keys in legacy networks metadataNonce = await getMetadata(legacyMetadataHost, { pub_key_X: oAuthPubkeyX, pub_key_Y: oAuthPubkeyY }); - const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.curve.n); + const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.n); finalPubKey = ecCurve.keyFromPrivate(privateKeyWithNonce.toString(16, 64), "hex").getPublic(); } } else { @@ -639,37 +745,67 @@ export async function retrieveOrImportShare(params: { throw new Error("Invalid public key, this might be a bug, please report this to web3auth team"); } - const oAuthKeyAddress = generateAddressFromPrivKey(ecCurve, oAuthKey); - - // deriving address from pub key coz pubkey is always available - // but finalPrivKey won't be available for v2 user upgraded to 2/n - const finalEvmAddress = generateAddressFromPubKey(ecCurve, finalPubKey.getX(), finalPubKey.getY()); - 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(ecCurve.curve.n); - finalPrivKey = privateKeyWithNonce.toString("hex", 64); - } - let isUpgraded: boolean | null = false; + const oAuthKeyAddress = generateAddressFromPrivKey(keyType, oAuthKey); + // deriving address from pub key coz pubkey is always available + // but finalPrivKey won't be available for v2 user upgraded to 2/n + const finalWalletAddress = generateAddressFromPubKey(keyType, finalPubKey.getX(), finalPubKey.getY()); + let keyWithNonce = ""; if (typeOfUser === "v1") { isUpgraded = null; } else if (typeOfUser === "v2") { isUpgraded = metadataNonce.eq(new BN("0")); } + + if (typeOfUser === "v1" || (typeOfUser === "v2" && metadataNonce.gt(new BN(0)))) { + const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.n); + keyWithNonce = privateKeyWithNonce.toString("hex", 64); + } + if (keyType === KEY_TYPE.SECP256K1) { + finalPrivKey = keyWithNonce; + } else if (keyType === KEY_TYPE.ED25519) { + if (keyWithNonce && !nonceResult.seed) { + throw new Error("Invalid data, seed data is missing for ed25519 key, Please report this bug"); + } else if (keyWithNonce && nonceResult.seed) { + // console.log("nonceResult.seed", nonceResult.seed, keyWithNonce); + const decryptedSeed = await decryptSeedData(nonceResult.seed, new BN(keyWithNonce, "hex")); + finalPrivKey = decryptedSeed.toString("hex"); + } + } else { + throw new Error(`Invalid keyType: ${keyType}`); + } + + let postboxKey = oAuthKey; + let postboxPubX = oAuthPubkeyX; + let postboxPubY = oAuthPubkeyY; + if (keyType === KEY_TYPE.ED25519) { + const { scalar, point } = getSecpKeyFromEd25519(privateKey); + postboxKey = scalar; + postboxPubX = point.getX().toString(16, 64); + postboxPubY = point.getY().toString(16, 64); + if (thresholdPubKey.SignerX.padStart(64, "0") !== postboxPubX || thresholdPubKey.SignerY.padStart(64, "0") !== postboxPubY) { + throw new Error("Invalid postbox key"); + } + } // return reconstructed private key and ethereum address return { finalKeyData: { - evmAddress: finalEvmAddress, + walletAddress: finalWalletAddress, X: finalPubKey.getX().toString(16, 64), // this is final pub x user before and after updating to 2/n Y: finalPubKey.getY().toString(16, 64), // this is final pub y user before and after updating to 2/n privKey: finalPrivKey, }, oAuthKeyData: { - evmAddress: oAuthKeyAddress, + walletAddress: oAuthKeyAddress, X: oAuthPubkeyX, Y: oAuthPubkeyY, - privKey: oAuthKey.toString("hex", 64).padStart(64, "0"), + privKey: oAuthKey.toString("hex", 64), + }, + postboxKeyData: { + privKey: postboxKey.toString("hex", 64), + X: postboxPubX, + Y: postboxPubY, }, sessionData: { sessionTokenData, diff --git a/src/interfaces.ts b/src/interfaces.ts index 1ad525e..b55a5e8 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -1,6 +1,9 @@ -import type { TORUS_NETWORK_TYPE } from "@toruslabs/constants"; +import type { INodePub, TORUS_NETWORK_TYPE } from "@toruslabs/constants"; import { Ecies } from "@toruslabs/eccrypto"; import BN from "bn.js"; +import { curve } from "elliptic"; + +import { TorusUtilsExtraParams } from "./TorusUtilsExtraParams"; export interface KeyIndex { index: string; @@ -9,14 +12,23 @@ export interface KeyIndex { } export type UserType = "v1" | "v2"; -export type v2NonceResultType = { typeOfUser: "v2"; nonce?: string; pubNonce: { x: string; y: string }; ipfs?: string; upgraded: boolean }; +export type v2NonceResultType = { + typeOfUser: "v2"; + nonce?: string; + seed?: string; + pubNonce: { x: string; y: string }; + ipfs?: string; + upgraded: boolean; +}; -export type v1NonceResultType = { typeOfUser: "v1"; nonce?: string }; +export type v1NonceResultType = { typeOfUser: "v1"; nonce?: string; seed?: string }; export type GetOrSetNonceResult = v2NonceResultType | v1NonceResultType; +export type KeyType = "secp256k1" | "ed25519"; export interface SetNonceData { operation: string; data: string; + seed?: string; timestamp: string; } @@ -26,11 +38,14 @@ export interface NonceMetadataParams { pub_key_Y: string; set_data: Partial; signature: string; + key_type?: KeyType; + seed?: string; } export interface TorusCtorOptions { clientId: string; network: TORUS_NETWORK_TYPE; + keyType?: KeyType; enableOneKey?: boolean; serverTimeOffset?: number; allowHost?: string; @@ -61,6 +76,7 @@ export interface CommitmentRequestResult { nodepubx: string; nodepuby: string; nodeindex: string; + pub_key_x: string; } export interface JRPCResponse { @@ -86,12 +102,15 @@ export type EciesHex = { [key in keyof Ecies]: string; } & { mode?: string }; +export interface ExtendedPublicKey { + X: string; + Y: string; + SignerX: string; + SignerY: string; +} export interface KeyAssignment { index: KeyIndex; - public_key: { - X: string; - Y: string; - }; + public_key: ExtendedPublicKey; threshold: string; node_index: string; // this is encrypted ciphertext @@ -115,10 +134,14 @@ export interface ShareRequestResult { } export interface ImportedShare { - pub_key_x: string; - pub_key_y: string; + oauth_pub_key_x: string; + oauth_pub_key_y: string; + final_user_point: curve.base.BasePoint; + signing_pub_key_x: string; + signing_pub_key_y: string; encrypted_share: string; encrypted_share_metadata: EciesHex; + encrypted_seed?: string; node_index: number; key_type: string; nonce_data: string; @@ -133,13 +156,15 @@ export interface SessionToken { node_puby: string; } export interface TorusPublicKey { + // based on curve type finalKeyData: { - evmAddress: string; + walletAddress: string; // format depends on key type X: string; // this is final pub x user before and after updating to 2/n Y: string; // this is final pub y user before and after updating to 2/n }; + // based on curve type oAuthKeyData: { - evmAddress: string; + walletAddress: string; // format depends on key type X: string; Y: string; }; @@ -162,6 +187,12 @@ export interface TorusKey { oAuthKeyData: TorusPublicKey["oAuthKeyData"] & { privKey: string; }; + // always secp key + postboxKeyData: { + X: string; + Y: string; + privKey: string; + }; sessionData: { sessionTokenData: SessionToken[]; sessionAuthKey: string; @@ -188,6 +219,7 @@ export interface MetadataParams { namespace?: string; pub_key_X: string; pub_key_Y: string; + key_type?: KeyType; set_data: { data: "getNonce" | "getOrSetNonce" | string; timestamp: string; @@ -195,6 +227,23 @@ export interface MetadataParams { signature: string; } +export interface PrivateKeyData { + oAuthKeyScalar: BN; + oAuthPubX: BN; + oAuthPubY: BN; + SigningPubX: BN; + SigningPubY: BN; + metadataNonce: BN; + metadataSigningKey: BN; + finalUserPubKeyPoint: curve.base.BasePoint; + encryptedSeed?: string; +} + +export interface EncryptedSeed { + enc_text: string; + public_key?: string; + metadata: EciesHex; +} export interface SapphireMetadataParams { namespace?: string; pub_key_X: string; @@ -206,3 +255,25 @@ export interface SapphireMetadataParams { }; signature?: string; } + +export interface ImportKeyParams { + endpoints: string[]; + nodeIndexes: number[]; + nodePubkeys: INodePub[]; + verifier: string; + verifierParams: VerifierParams; + idToken: string; + newPrivateKey: string; + extraParams?: TorusUtilsExtraParams; +} + +export interface RetrieveSharesParams { + endpoints: string[]; + indexes: number[]; + verifier: string; + verifierParams: VerifierParams; + idToken: string; + nodePubkeys: INodePub[]; + extraParams?: TorusUtilsExtraParams; + useDkg?: boolean; +} diff --git a/src/torus.ts b/src/torus.ts index 050b47e..404410c 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -1,33 +1,38 @@ -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 { + INodePub, + KEY_TYPE, + LEGACY_NETWORKS_ROUTE_MAP, + METADATA_MAP, + SIGNER_MAP, + TORUS_LEGACY_NETWORK_TYPE, + TORUS_NETWORK_TYPE, +} from "@toruslabs/constants"; 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 { - encParamsBufToHex, + encodeEd25519Point, generateAddressFromPubKey, - generateRandomPolynomial, + generateShares, + getEd25519ExtendedPublicKey, getMetadata, getOrSetNonce, GetOrSetNonceError, GetPubKeyOrKeyAssign, - keccak256, retrieveOrImportShare, } from "./helpers"; import { GetOrSetNonceResult, - ImportedShare, + ImportKeyParams, + KeyType, LegacyVerifierLookupResponse, - NonceMetadataParams, - SetNonceData, + RetrieveSharesParams, TorusCtorOptions, TorusKey, TorusPublicKey, v2NonceResultType, - VerifierParams, } from "./interfaces"; import log from "./loglevel"; @@ -50,10 +55,24 @@ class Torus { private legacyMetadataHost: string; - constructor({ enableOneKey = false, clientId, network, serverTimeOffset = 0, allowHost, legacyMetadataHost }: TorusCtorOptions) { - if (!clientId) throw Error("Please provide a valid clientId in constructor"); - if (!network) throw Error("Please provide a valid network in constructor"); - this.ec = new EC("secp256k1"); + private keyType: KeyType = KEY_TYPE.SECP256K1; + + constructor({ + enableOneKey = false, + clientId, + network, + serverTimeOffset = 0, + allowHost, + legacyMetadataHost, + keyType = KEY_TYPE.SECP256K1, + }: TorusCtorOptions) { + if (!clientId) throw new Error("Please provide a valid clientId in constructor"); + if (!network) throw new Error("Please provide a valid network in constructor"); + if (keyType === KEY_TYPE.ED25519 && LEGACY_NETWORKS_ROUTE_MAP[network as TORUS_LEGACY_NETWORK_TYPE]) { + throw new Error(`keyType: ${keyType} is not supported by ${network} network`); + } + this.keyType = keyType; + this.ec = new EC(this.keyType); this.serverTimeOffset = serverTimeOffset || 0; // ms this.network = network; this.clientId = clientId; @@ -87,37 +106,61 @@ class Torus { static getPostboxKey(torusKey: TorusKey): string { if (torusKey.metadata.typeOfUser === "v1") { - return torusKey.finalKeyData.privKey || torusKey.oAuthKeyData.privKey; + return torusKey.finalKeyData.privKey || torusKey.postboxKeyData.privKey; } - return torusKey.oAuthKeyData.privKey; + return torusKey.postboxKeyData.privKey; } - async retrieveShares( - endpoints: string[], - indexes: number[], - verifier: string, - verifierParams: VerifierParams, - idToken: string, - extraParams: Record = {} - ): Promise { + async retrieveShares(params: RetrieveSharesParams): Promise { + const { verifier, verifierParams, idToken, nodePubkeys, indexes, endpoints, useDkg, extraParams = {} } = params; + if (nodePubkeys.length === 0) { + throw new Error("nodePubkeys param is required"); + } + + if (nodePubkeys.length !== indexes.length) { + throw new Error("nodePubkeys length must be same as indexes length"); + } + + if (nodePubkeys.length !== endpoints.length) { + throw new Error("nodePubkeys length must be same as endpoints length"); + } + // dkg is used by default only for secp256k1 keys, + // for ed25519 keys import keys flows is the default + let shouldUseDkg; + if (typeof useDkg === "boolean") { + shouldUseDkg = useDkg; + } else if (this.keyType === KEY_TYPE.ED25519) { + shouldUseDkg = false; + } else { + shouldUseDkg = true; + } + if (!shouldUseDkg && nodePubkeys.length === 0) { + throw new Error("nodePubkeys param is required"); + } + + if (!extraParams.session_token_exp_second) { + extraParams.session_token_exp_second = Torus.sessionTime; + } + return retrieveOrImportShare({ legacyMetadataHost: this.legacyMetadataHost, serverTimeOffset: this.serverTimeOffset, enableOneKey: this.enableOneKey, ecCurve: this.ec, + keyType: this.keyType, allowHost: this.allowHost, network: this.network, clientId: this.clientId, endpoints, + indexes, verifier, verifierParams, idToken, - indexes, - importedShares: [], - extraParams: { - ...extraParams, - session_token_exp_second: Torus.sessionTime, - }, + useDkg: shouldUseDkg, + newImportedShares: [], + overrideExistingKey: false, + nodePubkeys, + extraParams, }); } @@ -130,62 +173,42 @@ class Torus { return this.getNewPublicAddress(endpoints, { verifier, verifierId, extendedVerifierId }, this.enableOneKey); } - async importPrivateKey( - endpoints: string[], - nodeIndexes: number[], - nodePubkeys: INodePub[], - verifier: string, - verifierParams: VerifierParams, - idToken: string, - newPrivateKey: string, - extraParams: Record = {} - ): Promise { + async importPrivateKey(params: ImportKeyParams): Promise { + const { nodeIndexes, newPrivateKey, verifier, verifierParams, idToken, nodePubkeys, endpoints, extraParams = {} } = params; + if (endpoints.length !== nodeIndexes.length) { throw new Error(`length of endpoints array must be same as length of nodeIndexes array`); } - const threshold = ~~(endpoints.length / 2) + 1; - const degree = threshold - 1; - const nodeIndexesBn: BN[] = []; - const key = this.ec.keyFromPrivate(newPrivateKey.padStart(64, "0"), "hex"); - for (const nodeIndex of nodeIndexes) { - nodeIndexesBn.push(new BN(nodeIndex)); + if (!extraParams.session_token_exp_second) { + extraParams.session_token_exp_second = Torus.sessionTime; } - const privKeyBn = key.getPrivate(); - const randomNonce = new BN(generatePrivate()); - - const oAuthKey = privKeyBn.sub(randomNonce).umod(this.ec.curve.n); - const oAuthPubKey = this.ec.keyFromPrivate(oAuthKey.toString("hex").padStart(64, "0")).getPublic(); - const poly = generateRandomPolynomial(this.ec, degree, oAuthKey); - const shares = poly.generateShares(nodeIndexesBn); - const nonceParams = this.generateNonceMetadataParams("getOrSetNonce", oAuthKey, randomNonce); - const nonceData = Buffer.from(stringify(nonceParams.set_data), "utf8").toString("base64"); - const sharesData: ImportedShare[] = []; - const encPromises: Promise[] = []; - for (let i = 0; i < nodeIndexesBn.length; i++) { - const shareJson = shares[nodeIndexesBn[i].toString("hex", 64)].toJSON() as Record; - if (!nodePubkeys[i]) { - throw new Error(`Missing node pub key for node index: ${nodeIndexesBn[i].toString("hex", 64)}`); + + let privKeyBuffer; + + if (this.keyType === KEY_TYPE.SECP256K1) { + privKeyBuffer = Buffer.from(newPrivateKey.padStart(64, "0"), "hex"); + if (privKeyBuffer.length !== 32) { + throw new Error("Invalid private key length for given secp256k1 key"); } - const nodePubKey = this.ec.keyFromPublic({ x: nodePubkeys[i].X, y: nodePubkeys[i].Y }); - encPromises.push(encrypt(Buffer.from(nodePubKey.getPublic().encodeCompressed("hex"), "hex"), Buffer.from(shareJson.share, "hex"))); } - const encShares = await Promise.all(encPromises); - for (let i = 0; i < nodeIndexesBn.length; i++) { - const shareJson = shares[nodeIndexesBn[i].toString("hex", 64)].toJSON() as Record; - const encParams = encShares[i]; - const encParamsMetadata = encParamsBufToHex(encParams); - const shareData: ImportedShare = { - pub_key_x: oAuthPubKey.getX().toString("hex", 64), - pub_key_y: oAuthPubKey.getY().toString("hex", 64), - encrypted_share: encParamsMetadata.ciphertext, - encrypted_share_metadata: encParamsMetadata, - node_index: Number.parseInt(shareJson.shareIndex, 16), - key_type: "secp256k1", - nonce_data: nonceData, - nonce_signature: nonceParams.signature, - }; - sharesData.push(shareData); + if (this.keyType === KEY_TYPE.ED25519) { + privKeyBuffer = Buffer.from(newPrivateKey.padStart(64, "0"), "hex"); + if (privKeyBuffer.length !== 32) { + throw new Error("Invalid private key length for given ed25519 key"); + } + } + + const sharesData = await generateShares(this.ec, this.keyType, this.serverTimeOffset, nodeIndexes, nodePubkeys, privKeyBuffer); + if (this.keyType === KEY_TYPE.ED25519) { + const ed25519Key = getEd25519ExtendedPublicKey(privKeyBuffer); + const ed25519PubKey = encodeEd25519Point(ed25519Key.point); + const encodedPubKey = encodeEd25519Point(sharesData[0].final_user_point); + const importedPubKey = Buffer.from(ed25519PubKey).toString("hex"); + const derivedPubKey = encodedPubKey.toString("hex"); + if (importedPubKey !== derivedPubKey) { + throw new Error("invalid shares data for ed25519 key, public key is not matching after generating shares"); + } } return retrieveOrImportShare({ @@ -193,19 +216,20 @@ class Torus { serverTimeOffset: this.serverTimeOffset, enableOneKey: this.enableOneKey, ecCurve: this.ec, + keyType: this.keyType, allowHost: this.allowHost, network: this.network, clientId: this.clientId, endpoints, + indexes: nodeIndexes, verifier, verifierParams, idToken, - indexes: nodeIndexes, - importedShares: sharesData, - extraParams: { - ...extraParams, - session_token_exp_second: Torus.sessionTime, - }, + useDkg: false, + overrideExistingKey: true, + newImportedShares: sharesData, + nodePubkeys, + extraParams, }); } @@ -215,32 +239,11 @@ class Torus { */ async getUserTypeAndAddress( endpoints: string[], - torusNodePubs: INodePub[], { verifier, verifierId, extendedVerifierId }: { verifier: string; verifierId: string; extendedVerifierId?: string } ): Promise { - log.info(torusNodePubs, { verifier, verifierId, extendedVerifierId }); return this.getNewPublicAddress(endpoints, { verifier, verifierId, extendedVerifierId }, true) as Promise; } - private generateNonceMetadataParams(operation: string, privateKey: BN, nonce?: BN): NonceMetadataParams { - const key = this.ec.keyFromPrivate(privateKey.toString("hex", 64)); - const setData: Partial = { - operation, - timestamp: new BN(~~(this.serverTimeOffset + Date.now() / 1000)).toString(16), - }; - - if (nonce) { - setData.data = nonce.toString("hex", 64); - } - const sig = key.sign(keccak256(Buffer.from(stringify(setData), "utf8")).slice(2)); - return { - pub_key_X: key.getPublic().getX().toString("hex", 64), - pub_key_Y: key.getPublic().getY().toString("hex", 64), - set_data: setData, - signature: Buffer.from(sig.r.toString(16, 64) + sig.s.toString(16, 64) + new BN("").toString(16, 2), "hex").toString("base64"), - }; - } - private async getNewPublicAddress( endpoints: string[], { verifier, verifierId, extendedVerifierId }: { verifier: string; verifierId: string; extendedVerifierId?: string }, @@ -251,8 +254,10 @@ class Torus { network: this.network, verifier, verifierId, + keyType: this.keyType, extendedVerifierId, }); + const { errorResult, keyResult, nodeIndexes = [], serverTimeOffset } = keyAssignResult; const finalServerTimeOffset = this.serverTimeOffset || serverTimeOffset; const { nonceResult } = keyAssignResult; @@ -307,22 +312,22 @@ class Torus { } const oAuthX = oAuthPubKey.getX().toString(16, 64); const oAuthY = oAuthPubKey.getY().toString(16, 64); - const oAuthAddress = generateAddressFromPubKey(this.ec, oAuthPubKey.getX(), oAuthPubKey.getY()); + const oAuthAddress = generateAddressFromPubKey(this.keyType, oAuthPubKey.getX(), oAuthPubKey.getY()); if (!finalPubKey) { throw new Error("Unable to derive finalPubKey"); } const finalX = finalPubKey ? finalPubKey.getX().toString(16, 64) : ""; const finalY = finalPubKey ? finalPubKey.getY().toString(16, 64) : ""; - const finalAddress = finalPubKey ? generateAddressFromPubKey(this.ec, finalPubKey.getX(), finalPubKey.getY()) : ""; + const finalAddress = finalPubKey ? generateAddressFromPubKey(this.keyType, finalPubKey.getX(), finalPubKey.getY()) : ""; return { oAuthKeyData: { - evmAddress: oAuthAddress, + walletAddress: oAuthAddress, X: oAuthX, Y: oAuthY, }, finalKeyData: { - evmAddress: finalAddress, + walletAddress: finalAddress, X: finalX, Y: finalY, }, @@ -393,22 +398,22 @@ class Torus { } const oAuthX = oAuthPubKey.getX().toString(16, 64); const oAuthY = oAuthPubKey.getY().toString(16, 64); - const oAuthAddress = generateAddressFromPubKey(this.ec, oAuthPubKey.getX(), oAuthPubKey.getY()); + const oAuthAddress = generateAddressFromPubKey(this.keyType, oAuthPubKey.getX(), oAuthPubKey.getY()); if (typeOfUser === "v2" && !finalPubKey) { throw new Error("Unable to derive finalPubKey"); } const finalX = finalPubKey ? finalPubKey.getX().toString(16, 64) : ""; const finalY = finalPubKey ? finalPubKey.getY().toString(16, 64) : ""; - const finalAddress = finalPubKey ? generateAddressFromPubKey(this.ec, finalPubKey.getX(), finalPubKey.getY()) : ""; + const finalAddress = finalPubKey ? generateAddressFromPubKey(this.keyType, finalPubKey.getX(), finalPubKey.getY()) : ""; return { oAuthKeyData: { - evmAddress: oAuthAddress, + walletAddress: oAuthAddress, X: oAuthX, Y: oAuthY, }, finalKeyData: { - evmAddress: finalAddress, + walletAddress: finalAddress, X: finalX, Y: finalY, }, diff --git a/test/aqua.test.ts b/test/aqua.test.ts index d8f8ba3..765cb71 100644 --- a/test/aqua.test.ts +++ b/test/aqua.test.ts @@ -6,7 +6,7 @@ import faker from "faker"; import { keccak256, TorusPublicKey } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken } from "./helpers"; +import { generateIdToken, getRetrieveSharesParams } from "./helpers"; const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; @@ -29,18 +29,18 @@ describe("torus utils aqua", function () { 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("0xDfA967285AC699A70DA340F60d00DB19A272639d"); + expect(result.finalKeyData.walletAddress).to.equal("0xDfA967285AC699A70DA340F60d00DB19A272639d"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d", + walletAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d", X: "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d", Y: "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c", }, finalKeyData: { - evmAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d", + walletAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d", X: "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d", Y: "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c", }, @@ -57,20 +57,20 @@ describe("torus utils aqua", function () { it("should fetch user type and public address", async function () { const verifier = "tkey-google-aqua"; // any verifier const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const result1 = (await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, verifierDetails)) as TorusPublicKey; + const { torusNodeEndpoints } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const result1 = (await torus.getUserTypeAndAddress(torusNodeEndpoints, verifierDetails)) as TorusPublicKey; expect(result1.metadata.typeOfUser).to.equal("v2"); expect(result1.metadata.serverTimeOffset).lessThan(20); delete result1.metadata.serverTimeOffset; expect(result1).eql({ oAuthKeyData: { - evmAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d", + walletAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d", X: "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d", Y: "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c", }, finalKeyData: { - evmAddress: "0x79F06350eF34Aeed4BE68e26954D405D573f1438", + walletAddress: "0x79F06350eF34Aeed4BE68e26954D405D573f1438", X: "99df45abc8e6ee03d2f94df33be79e939eadfbed20c6b88492782fdc3ef1dfd3", Y: "12bf3e54599a177fdb88f8b22419df7ddf1622e1d2344301edbe090890a72b16", }, @@ -89,7 +89,7 @@ describe("torus utils aqua", function () { const v2Verifier = "tkey-google-aqua"; // 1/1 user const v2TestEmail = "somev2user@gmail.com"; - const result2 = (await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, { + const result2 = (await torus.getUserTypeAndAddress(torusNodeEndpoints, { verifier: v2Verifier, verifierId: v2TestEmail, })) as TorusPublicKey; @@ -99,12 +99,12 @@ describe("torus utils aqua", function () { expect(result2).eql({ oAuthKeyData: { - evmAddress: "0x4ea5260fF85678A2a326D08DF9C44d1f559a5828", + walletAddress: "0x4ea5260fF85678A2a326D08DF9C44d1f559a5828", X: "0e6febe33a9d4eeb680cc6b63ff6237ad1971f27adcd7f104a3b1de18eda9337", Y: "a5a915561f3543688e71281a850b9ee10b9690f305d9e79028dfc8359192b82d", }, finalKeyData: { - evmAddress: "0xBc32f315515AdE7010cabC5Fd68c966657A570BD", + walletAddress: "0xBc32f315515AdE7010cabC5Fd68c966657A570BD", X: "4897f120584ee18a72b9a6bb92c3ef6e45fc5fdff70beae7dc9325bd01332022", Y: "2066dbef2fcdded4573e3c04d1c04edd5d44662168e636ed9d0b0cbe2e67c968", }, @@ -122,7 +122,7 @@ describe("torus utils aqua", function () { // 2/n user const v2nTestEmail = "caspertorus@gmail.com"; - const result3 = (await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, { + const result3 = (await torus.getUserTypeAndAddress(torusNodeEndpoints, { verifier: v2Verifier, verifierId: v2nTestEmail, })) as TorusPublicKey; @@ -132,12 +132,12 @@ describe("torus utils aqua", function () { expect(result3.metadata.typeOfUser).to.equal("v2"); expect(result3).eql({ oAuthKeyData: { - evmAddress: "0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD", + walletAddress: "0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD", X: "e76d2f7fa2c0df324b4ab74629c3af47aa4609c35f1d2b6b90b77a47ab9a1281", Y: "b33b35148d72d357070f66372e07fec436001bdb15c098276b120b9ed64c1e5f", }, finalKeyData: { - evmAddress: "0x5469C5aCB0F30929226AfF4622918DA8E1424a8D", + walletAddress: "0x5469C5aCB0F30929226AfF4622918DA8E1424a8D", X: "c20fac685bb67169e92f1d5d8894d4eea18753c0ef3b7b1b2224233b2dfa3539", Y: "c4f080b5c8d5c55c8eaba4bec70f668f36db4126f358b491d631fefea7c19d21", }, @@ -160,10 +160,10 @@ describe("torus utils aqua", function () { const verifierDetails = { verifier, verifierId: email }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const { finalKeyData, oAuthKeyData, metadata } = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(finalKeyData.evmAddress).to.not.equal(""); - expect(finalKeyData.evmAddress).to.not.equal(null); - expect(oAuthKeyData.evmAddress).to.not.equal(""); - expect(oAuthKeyData.evmAddress).to.not.equal(null); + expect(finalKeyData.walletAddress).to.not.equal(""); + expect(finalKeyData.walletAddress).to.not.equal(null); + expect(oAuthKeyData.walletAddress).to.not.equal(""); + expect(oAuthKeyData.walletAddress).to.not.equal(null); expect(metadata.typeOfUser).to.equal("v1"); expect(metadata.upgraded).to.equal(false); }); @@ -171,21 +171,28 @@ describe("torus utils aqua", function () { it("should be able to login", async function () { const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const result = await torus.retrieveShares(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const result = await torus.retrieveShares( + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, torusNodePub) + ); expect(result.finalKeyData.privKey).to.be.equal("f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ finalKeyData: { - evmAddress: "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195", + walletAddress: "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195", X: "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664", Y: "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f", privKey: "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d", // TODO: fix this privKey }, oAuthKeyData: { - evmAddress: "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195", + walletAddress: "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195", + X: "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664", + Y: "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f", + privKey: "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d", + }, + postboxKeyData: { X: "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664", Y: "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f", privKey: "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d", @@ -200,32 +207,40 @@ describe("torus utils aqua", function () { const idToken = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const hashedIdToken = keccak256(Buffer.from(idToken, "utf8")); const verifierDetails = { verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: TORUS_TEST_EMAIL, - }, - hashedIdToken.substring(2) + getRetrieveSharesParams( + torusNodeEndpoints, + torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: TORUS_TEST_EMAIL, + }, + hashedIdToken.substring(2), + torusNodePub + ) ); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; - expect(result.oAuthKeyData.evmAddress).to.be.equal("0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D"); - expect(result.finalKeyData.evmAddress).to.be.equal("0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D"); + expect(result.oAuthKeyData.walletAddress).to.be.equal("0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D"); + expect(result.finalKeyData.walletAddress).to.be.equal("0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D"); expect(result).eql({ finalKeyData: { - evmAddress: "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D", + walletAddress: "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D", X: "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d", Y: "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10", privKey: "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355", }, oAuthKeyData: { - evmAddress: "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D", + walletAddress: "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D", + X: "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d", + Y: "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10", + privKey: "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355", + }, + postboxKeyData: { X: "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d", Y: "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10", privKey: "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355", diff --git a/test/celeste.test.ts b/test/celeste.test.ts index 476b46b..6f365f8 100644 --- a/test/celeste.test.ts +++ b/test/celeste.test.ts @@ -6,7 +6,7 @@ import faker from "faker"; import { keccak256 } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken } from "./helpers"; +import { generateIdToken, getRetrieveSharesParams } from "./helpers"; const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; @@ -29,7 +29,7 @@ describe("torus utils celeste", function () { 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("0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113"); + expect(result.finalKeyData.walletAddress).to.equal("0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; @@ -37,12 +37,12 @@ describe("torus utils celeste", function () { oAuthKeyData: { X: "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9", Y: "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb", - evmAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", + walletAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", }, finalKeyData: { X: "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9", Y: "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb", - evmAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", + walletAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", }, metadata: { pubNonce: undefined, @@ -57,9 +57,9 @@ describe("torus utils celeste", function () { it("should fetch user type and 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 result1 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(result1.finalKeyData.evmAddress).to.equal("0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113"); + const { torusNodeEndpoints } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const result1 = await torus.getUserTypeAndAddress(torusNodeEndpoints, verifierDetails); + expect(result1.finalKeyData.walletAddress).to.equal("0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113"); expect(result1.metadata.typeOfUser).to.equal("v1"); expect(result1.metadata.serverTimeOffset).lessThan(20); delete result1.metadata.serverTimeOffset; @@ -68,12 +68,12 @@ describe("torus utils celeste", function () { oAuthKeyData: { X: "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9", Y: "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb", - evmAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", + walletAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", }, finalKeyData: { X: "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9", Y: "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb", - evmAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", + walletAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", }, metadata: { pubNonce: undefined, @@ -87,11 +87,11 @@ describe("torus utils celeste", function () { const v2Verifier = "tkey-google-celeste"; // 1/1 user const v2TestEmail = "somev2user@gmail.com"; - const result2 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, { + const result2 = await torus.getUserTypeAndAddress(torusNodeEndpoints, { verifier: v2Verifier, verifierId: v2TestEmail, }); - expect(result2.finalKeyData.evmAddress).to.equal("0x8d69CE354DA39413f205FdC8680dE1F3FBBb36e2"); + expect(result2.finalKeyData.walletAddress).to.equal("0x8d69CE354DA39413f205FdC8680dE1F3FBBb36e2"); expect(result2.metadata.typeOfUser).to.equal("v2"); delete result2.metadata.serverTimeOffset; @@ -99,12 +99,12 @@ describe("torus utils celeste", function () { oAuthKeyData: { X: "cfa646a2949ebe559205c5c407d734d1b6927f2ea5fbeabfcbc31ab9a985a336", Y: "8f988eb8b59515293820aa38af172b153e8d25307db8d5f410407c20e062b6e6", - evmAddress: "0xda4afB35493094Dd2C05b186Ca0FABAD96491B21", + walletAddress: "0xda4afB35493094Dd2C05b186Ca0FABAD96491B21", }, finalKeyData: { X: "5962144e03b993b0e503eb4e6e0196427f9fc9472f0dfd1be2ca5d4939f91680", Y: "f6e81f01f483110badab18371237d15834f9ecf31c3588c165dae32ec446ac38", - evmAddress: "0x8d69CE354DA39413f205FdC8680dE1F3FBBb36e2", + walletAddress: "0x8d69CE354DA39413f205FdC8680dE1F3FBBb36e2", }, metadata: { pubNonce: { @@ -120,24 +120,24 @@ describe("torus utils celeste", function () { // 2/n user const v2nTestEmail = "caspertorus@gmail.com"; - const result3 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, { + const result3 = await torus.getUserTypeAndAddress(torusNodeEndpoints, { verifier: v2Verifier, verifierId: v2nTestEmail, }); delete result3.metadata.serverTimeOffset; - expect(result3.finalKeyData.evmAddress).to.equal("0x8108c29976C458e76f797AD55A3715Ce80a3fe78"); + expect(result3.finalKeyData.walletAddress).to.equal("0x8108c29976C458e76f797AD55A3715Ce80a3fe78"); expect(result3.metadata.typeOfUser).to.equal("v2"); expect(result3).eql({ oAuthKeyData: { X: "0cc857201e6c304dd893b243e323fe95982e5a99c0994cf902efa2432a672eb4", Y: "37a2f53c250b3e1186e38ece3dfcbcb23e325913038703531831b96d3e7b54cc", - evmAddress: "0xc8c4748ec135196fb482C761da273C31Ec48B099", + walletAddress: "0xc8c4748ec135196fb482C761da273C31Ec48B099", }, finalKeyData: { X: "e95fe2d595ade03f56d9c9a147fbb67705041704f147576fa4a8afbe7dc69470", Y: "3e20e4b331466769c4dd78f4561bfb2849010b4005b09c2ed082380326724ebe", - evmAddress: "0x8108c29976C458e76f797AD55A3715Ce80a3fe78", + walletAddress: "0x8108c29976C458e76f797AD55A3715Ce80a3fe78", }, metadata: { pubNonce: { @@ -158,10 +158,10 @@ describe("torus utils celeste", function () { const verifierDetails = { verifier, verifierId: email }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const { finalKeyData, metadata, oAuthKeyData } = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(finalKeyData.evmAddress).to.not.equal(""); - expect(finalKeyData.evmAddress).to.not.equal(null); - expect(oAuthKeyData.evmAddress).to.not.equal(""); - expect(oAuthKeyData.evmAddress).to.not.equal(null); + expect(finalKeyData.walletAddress).to.not.equal(""); + expect(finalKeyData.walletAddress).to.not.equal(null); + expect(oAuthKeyData.walletAddress).to.not.equal(""); + expect(oAuthKeyData.walletAddress).to.not.equal(null); expect(metadata.typeOfUser).to.equal("v1"); expect(metadata.upgraded).to.equal(false); }); @@ -169,8 +169,10 @@ describe("torus utils celeste", function () { it("should be able to login", async function () { const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const result = await torus.retrieveShares(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const result = await torus.retrieveShares( + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, torusNodePub) + ); expect(result.finalKeyData.privKey).to.be.equal("0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914"); expect(result.metadata.serverTimeOffset).lessThan(20); @@ -178,13 +180,18 @@ describe("torus utils celeste", function () { expect(result).eql({ finalKeyData: { - evmAddress: "0x58420FB83971C4490D8c9B091f8bfC890D716617", + walletAddress: "0x58420FB83971C4490D8c9B091f8bfC890D716617", X: "73b82ce0f8201a962636d404fe7a683f37c2267a9528576e1dac9964940add74", Y: "6d28c46c5385b90322bde74d6c5096e154eae2838399f4d6e8d752f7b0c449c1", privKey: "0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914", }, oAuthKeyData: { - evmAddress: "0x58420FB83971C4490D8c9B091f8bfC890D716617", + walletAddress: "0x58420FB83971C4490D8c9B091f8bfC890D716617", + X: "73b82ce0f8201a962636d404fe7a683f37c2267a9528576e1dac9964940add74", + Y: "6d28c46c5385b90322bde74d6c5096e154eae2838399f4d6e8d752f7b0c449c1", + privKey: "0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914", + }, + postboxKeyData: { X: "73b82ce0f8201a962636d404fe7a683f37c2267a9528576e1dac9964940add74", Y: "6d28c46c5385b90322bde74d6c5096e154eae2838399f4d6e8d752f7b0c449c1", privKey: "0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914", @@ -199,33 +206,41 @@ describe("torus utils celeste", function () { const idToken = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const hashedIdToken = keccak256(Buffer.from(idToken, "utf8")); const verifierDetails = { verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: TORUS_TEST_EMAIL, - }, - hashedIdToken.substring(2) + getRetrieveSharesParams( + torusNodeEndpoints, + torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: TORUS_TEST_EMAIL, + }, + hashedIdToken.substring(2), + torusNodePub + ) ); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; - expect(result.oAuthKeyData.evmAddress).to.be.equal("0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564"); - expect(result.finalKeyData.evmAddress).to.be.equal("0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564"); + expect(result.oAuthKeyData.walletAddress).to.be.equal("0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564"); + expect(result.finalKeyData.walletAddress).to.be.equal("0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564"); expect(result).eql({ finalKeyData: { - evmAddress: "0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564", + walletAddress: "0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564", X: "df6eb11d52e76b388a44896e9442eda17096c2b67b0be957a4ba0b68a70111ca", Y: "bfd29ab1e97b3f7c444bb3e7ad0acb39d72589371387436c7d623d1e83f3d6eb", privKey: "356305761eca57f27b09700d76456ad627b084152725dbfdfcfa0abcd9d4f17e", }, oAuthKeyData: { - evmAddress: "0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564", + walletAddress: "0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564", + X: "df6eb11d52e76b388a44896e9442eda17096c2b67b0be957a4ba0b68a70111ca", + Y: "bfd29ab1e97b3f7c444bb3e7ad0acb39d72589371387436c7d623d1e83f3d6eb", + privKey: "356305761eca57f27b09700d76456ad627b084152725dbfdfcfa0abcd9d4f17e", + }, + postboxKeyData: { X: "df6eb11d52e76b388a44896e9442eda17096c2b67b0be957a4ba0b68a70111ca", Y: "bfd29ab1e97b3f7c444bb3e7ad0acb39d72589371387436c7d623d1e83f3d6eb", privKey: "356305761eca57f27b09700d76456ad627b084152725dbfdfcfa0abcd9d4f17e", diff --git a/test/cyan.test.ts b/test/cyan.test.ts index eac782b..10aa432 100644 --- a/test/cyan.test.ts +++ b/test/cyan.test.ts @@ -6,7 +6,7 @@ import faker from "faker"; import { keccak256 } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken } from "./helpers"; +import { generateIdToken, getRetrieveSharesParams } from "./helpers"; const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; @@ -29,19 +29,19 @@ describe("torus utils cyan", function () { 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("0xA3767911A84bE6907f26C572bc89426dDdDB2825"); + expect(result.finalKeyData.walletAddress).to.equal("0xA3767911A84bE6907f26C572bc89426dDdDB2825"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825", + walletAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825", X: "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a", Y: "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1", }, finalKeyData: { - evmAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825", + walletAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825", X: "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a", Y: "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1", }, @@ -58,21 +58,21 @@ describe("torus utils cyan", function () { it("should fetch user type and public address", async function () { const verifier = "tkey-google-cyan"; // any verifier 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("0x3507F0d192a44E436B8a6C32a37d57D022861b1a"); + const { torusNodeEndpoints } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const result1 = await torus.getUserTypeAndAddress(torusNodeEndpoints, verifierDetails); + expect(result1.finalKeyData.walletAddress).to.equal("0x3507F0d192a44E436B8a6C32a37d57D022861b1a"); expect(result1.metadata.typeOfUser).to.equal("v2"); expect(result1.metadata.serverTimeOffset).lessThan(20); delete result1.metadata.serverTimeOffset; expect(result1).eql({ oAuthKeyData: { - evmAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825", + walletAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825", X: "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a", Y: "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1", }, finalKeyData: { - evmAddress: "0x3507F0d192a44E436B8a6C32a37d57D022861b1a", + walletAddress: "0x3507F0d192a44E436B8a6C32a37d57D022861b1a", X: "8aaadab9530cb157d0b0dfb7b27d1a3aaca45274563c22c92c77ee2191779051", Y: "d57b89d9f62bb6609d8542c3057943805c8c72f6f27d39781b820f27d7210f12", }, @@ -91,7 +91,7 @@ describe("torus utils cyan", function () { const v2Verifier = "tkey-google-cyan"; // 1/1 user const v2TestEmail = "somev2user@gmail.com"; - const result2 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, { + const result2 = await torus.getUserTypeAndAddress(torusNodeEndpoints, { verifier: v2Verifier, verifierId: v2TestEmail, }); @@ -99,16 +99,16 @@ describe("torus utils cyan", function () { delete result2.metadata.serverTimeOffset; - expect(result2.finalKeyData.evmAddress).to.equal("0x8EA83Ace86EB414747F2b23f03C38A34E0217814"); + expect(result2.finalKeyData.walletAddress).to.equal("0x8EA83Ace86EB414747F2b23f03C38A34E0217814"); expect(result2.metadata.typeOfUser).to.equal("v2"); expect(result2).eql({ oAuthKeyData: { - evmAddress: "0x29446f428293a4E6470AEaEDa6EAfA0F842EF54e", + walletAddress: "0x29446f428293a4E6470AEaEDa6EAfA0F842EF54e", X: "8b6f2048aba8c7833e3b02c5b6522bb18c484ad0025156e428f17fb8d8c34021", Y: "cd9ba153ff89d665f655d1be4c6912f3ff93996e6fe580d89e78bf1476fef2aa", }, finalKeyData: { - evmAddress: "0x8EA83Ace86EB414747F2b23f03C38A34E0217814", + walletAddress: "0x8EA83Ace86EB414747F2b23f03C38A34E0217814", X: "cbe7b0f0332e5583c410fcacb6d4ff685bec053cfd943ac75f5e4aa3278a6fbb", Y: "b525c463f438c7a3c4b018c8c5d16c9ef33b9ac6f319140a22b48b17bdf532dd", }, @@ -125,22 +125,22 @@ describe("torus utils cyan", function () { }); // 2/n user const v2nTestEmail = "caspertorus@gmail.com"; - const result3 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, { + const result3 = await torus.getUserTypeAndAddress(torusNodeEndpoints, { verifier: v2Verifier, verifierId: v2nTestEmail, }); delete result3.metadata.serverTimeOffset; - expect(result3.finalKeyData.evmAddress).to.equal("0xCC1f953f6972a9e3d685d260399D6B85E2117561"); + expect(result3.finalKeyData.walletAddress).to.equal("0xCC1f953f6972a9e3d685d260399D6B85E2117561"); expect(result3.metadata.typeOfUser).to.equal("v2"); expect(result3).eql({ oAuthKeyData: { - evmAddress: "0xe8a19482cbe5FaC896A5860Ca4156fb999DDc73b", + walletAddress: "0xe8a19482cbe5FaC896A5860Ca4156fb999DDc73b", X: "c491ba39155594896b27cf71a804ccf493289d918f40e6ba4d590f1c76139e9e", Y: "d4649ed9e46461e1af00399a4c65fabb1dc219b3f4af501a7d635c17f57ab553", }, finalKeyData: { - evmAddress: "0xCC1f953f6972a9e3d685d260399D6B85E2117561", + walletAddress: "0xCC1f953f6972a9e3d685d260399D6B85E2117561", X: "8d784434becaad9b23d9293d1f29c4429447315c4cac824cbf2eb21d3f7d79c8", Y: "fe46a0ef5efe33d16f6cfa678a597be930fbec5432cbb7f3580189c18bd7e157", }, @@ -163,10 +163,10 @@ describe("torus utils cyan", function () { const verifierDetails = { verifier, verifierId: email }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const { finalKeyData, oAuthKeyData, metadata } = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(finalKeyData.evmAddress).to.not.equal(""); - expect(finalKeyData.evmAddress).to.not.equal(null); - expect(oAuthKeyData.evmAddress).to.not.equal(""); - expect(oAuthKeyData.evmAddress).to.not.equal(null); + expect(finalKeyData.walletAddress).to.not.equal(""); + expect(finalKeyData.walletAddress).to.not.equal(null); + expect(oAuthKeyData.walletAddress).to.not.equal(""); + expect(oAuthKeyData.walletAddress).to.not.equal(null); expect(metadata.typeOfUser).to.equal("v1"); expect(metadata.upgraded).to.equal(false); }); @@ -174,8 +174,10 @@ describe("torus utils cyan", function () { it("should be able to login", async function () { const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const result = await torus.retrieveShares(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const result = await torus.retrieveShares( + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, torusNodePub) + ); delete result.sessionData; expect(result.metadata.serverTimeOffset).lessThan(20); @@ -186,13 +188,18 @@ describe("torus utils cyan", function () { finalKeyData: { X: "e2ed6033951af2851d1bea98799e62fb1ff24b952c1faea17922684678ba42d1", Y: "beef0efad88e81385952c0068ca48e8b9c2121be87cb0ddf18a68806db202359", - evmAddress: "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9", + walletAddress: "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9", privKey: "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8", }, oAuthKeyData: { X: "e2ed6033951af2851d1bea98799e62fb1ff24b952c1faea17922684678ba42d1", Y: "beef0efad88e81385952c0068ca48e8b9c2121be87cb0ddf18a68806db202359", - evmAddress: "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9", + walletAddress: "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9", + privKey: "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8", + }, + postboxKeyData: { + X: "e2ed6033951af2851d1bea98799e62fb1ff24b952c1faea17922684678ba42d1", + Y: "beef0efad88e81385952c0068ca48e8b9c2121be87cb0ddf18a68806db202359", privKey: "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8", }, metadata: { pubNonce: undefined, nonce: new BN(0), typeOfUser: "v1", upgraded: null }, @@ -204,34 +211,42 @@ describe("torus utils cyan", function () { const idToken = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const hashedIdToken = keccak256(Buffer.from(idToken, "utf8")); const verifierDetails = { verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: TORUS_TEST_EMAIL, - }, - hashedIdToken.substring(2) + getRetrieveSharesParams( + torusNodeEndpoints, + torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: TORUS_TEST_EMAIL, + }, + hashedIdToken.substring(2), + torusNodePub + ) ); delete result.sessionData; expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; - expect(result.oAuthKeyData.evmAddress).to.be.equal("0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04"); - expect(result.finalKeyData.evmAddress).to.be.equal("0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04"); + expect(result.oAuthKeyData.walletAddress).to.be.equal("0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04"); + expect(result.finalKeyData.walletAddress).to.be.equal("0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04"); expect(result).eql({ finalKeyData: { - evmAddress: "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04", + walletAddress: "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04", X: "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223", Y: "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd", privKey: "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf", }, oAuthKeyData: { - evmAddress: "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04", + walletAddress: "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04", + X: "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223", + Y: "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd", + privKey: "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf", + }, + postboxKeyData: { X: "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223", Y: "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd", privKey: "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf", diff --git a/test/helpers.ts b/test/helpers.ts index 73727b5..a196b8a 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -1,12 +1,14 @@ +import { INodePub } from "@toruslabs/constants"; import { generateJsonRPCObject, post } from "@toruslabs/http-helpers"; import dotenv from "dotenv"; import jwt, { Algorithm } from "jsonwebtoken"; -import { JRPCResponse } from "../src"; +import { ImportKeyParams, JRPCResponse, RetrieveSharesParams, VerifierParams } from "../src"; import { config } from "../src/config"; +import { TorusUtilsExtraParams } from "../src/TorusUtilsExtraParams"; dotenv.config({ path: `.env.${process.env.NODE_ENV}` }); -const jwtPrivateKey = `-----BEGIN PRIVATE KEY-----\n${process.env.JWT_PRIVATE_KEY}\n-----END PRIVATE KEY-----`; +const jwtPrivateKey = `-----BEGIN PRIVATE KEY-----\nMEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCCD7oLrcKae+jVZPGx52Cb/lKhdKxpXjl9eGNa1MlY57A==\n-----END PRIVATE KEY-----`; export const generateIdToken = (email: string, alg: Algorithm) => { const iat = Math.floor(Date.now() / 1000); const payload = { @@ -38,7 +40,51 @@ export const lookupVerifier = (endpoint: string, pubKeyX: string, pubKeyY: strin pub_key_x: pubKeyX, pub_key_y: pubKeyY, }), - null, + {}, { logTracingHeader: config.logRequestTracing } ); }; + +export const getRetrieveSharesParams = ( + endpoints: string[], + indexes: number[], + verifier: string, + verifierParams: VerifierParams, + idToken: string, + nodePubkeys: INodePub[], + extraParams: TorusUtilsExtraParams = {}, + useDkg?: boolean +): RetrieveSharesParams => { + return { + endpoints, + indexes, + verifier, + verifierParams, + idToken, + nodePubkeys, + extraParams, + useDkg, + }; +}; + +export const getImportKeyParams = ( + endpoints: string[], + nodeIndexes: number[], + nodePubkeys: INodePub[], + verifier: string, + verifierParams: VerifierParams, + idToken: string, + newPrivateKey: string, + extraParams: TorusUtilsExtraParams = {} +): ImportKeyParams => { + return { + endpoints, + nodeIndexes, + nodePubkeys, + verifier, + verifierParams, + idToken, + newPrivateKey, + extraParams, + }; +}; diff --git a/test/mainnet.test.ts b/test/mainnet.test.ts index a19aef6..f23dc9f 100644 --- a/test/mainnet.test.ts +++ b/test/mainnet.test.ts @@ -6,7 +6,7 @@ import faker from "faker"; import { keccak256 } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken } from "./helpers"; +import { generateIdToken, getRetrieveSharesParams } from "./helpers"; const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; @@ -29,17 +29,17 @@ describe("torus utils mainnet", function () { 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("0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A"); + expect(result.finalKeyData.walletAddress).to.equal("0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A"); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", + walletAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", X: "3b5655d78978b6fd132562b5cb66b11bcd868bd2a9e16babe4a1ca50178e57d4", Y: "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1", }, finalKeyData: { - evmAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", + walletAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", X: "3b5655d78978b6fd132562b5cb66b11bcd868bd2a9e16babe4a1ca50178e57d4", Y: "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1", }, @@ -56,8 +56,8 @@ describe("torus utils mainnet", function () { it("should fetch user type and public address", async function () { const verifier = "google"; // any verifier const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const result1 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, verifierDetails); + const { torusNodeEndpoints } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const result1 = await torus.getUserTypeAndAddress(torusNodeEndpoints, verifierDetails); expect(result1.metadata.typeOfUser).to.equal("v2"); expect(result1.metadata.serverTimeOffset).lessThan(20); @@ -65,12 +65,12 @@ describe("torus utils mainnet", function () { expect(result1).eql({ oAuthKeyData: { - evmAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", + walletAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", X: "3b5655d78978b6fd132562b5cb66b11bcd868bd2a9e16babe4a1ca50178e57d4", Y: "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1", }, finalKeyData: { - evmAddress: "0xb2e1c3119f8D8E73de7eaF7A535FB39A3Ae98C5E", + walletAddress: "0xb2e1c3119f8D8E73de7eaF7A535FB39A3Ae98C5E", X: "072beda348a832aed06044a258cb6a8d428ec7c245c5da92db5da4f3ab433e55", Y: "54ace0d3df2504fa29f17d424a36a0f92703899fad0afee93d010f6d84b310e5", }, @@ -89,7 +89,7 @@ describe("torus utils mainnet", function () { const v2Verifier = "tkey-google"; // 1/1 user const v2TestEmail = "somev2user@gmail.com"; - const result2 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, { + const result2 = await torus.getUserTypeAndAddress(torusNodeEndpoints, { verifier: v2Verifier, verifierId: v2TestEmail, }); @@ -97,16 +97,16 @@ describe("torus utils mainnet", function () { delete result2.metadata.serverTimeOffset; - expect(result2.finalKeyData.evmAddress).to.equal("0xFf669A15bFFcf32D3C5B40bE9E5d409d60D43526"); + expect(result2.finalKeyData.walletAddress).to.equal("0xFf669A15bFFcf32D3C5B40bE9E5d409d60D43526"); expect(result2.metadata.typeOfUser).to.equal("v2"); expect(result2).eql({ oAuthKeyData: { - evmAddress: "0xA9c6829e4899b6D630130ebf59D046CA868D7f83", + walletAddress: "0xA9c6829e4899b6D630130ebf59D046CA868D7f83", X: "5566cd940ea540ba1a3ba2ff0f5fd3d9a3a74350ac3baf47b811592ae6ea1c30", Y: "07a302e87e8d9eb5d143f570c248657288c13c09ecbe1e3a8720449daf9315b0", }, finalKeyData: { - evmAddress: "0xFf669A15bFFcf32D3C5B40bE9E5d409d60D43526", + walletAddress: "0xFf669A15bFFcf32D3C5B40bE9E5d409d60D43526", X: "bbfd26b1e61572c4e991a21b64f12b313cb6fce6b443be92d4d5fd8f311e8f33", Y: "df2c905356ec94faaa111a886be56ed6fa215b7facc1d1598486558355123c25", }, @@ -124,7 +124,7 @@ describe("torus utils mainnet", function () { // 2/n user const v2nTestEmail = "caspertorus@gmail.com"; - const result3 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, { + const result3 = await torus.getUserTypeAndAddress(torusNodeEndpoints, { verifier: v2Verifier, verifierId: v2nTestEmail, }); @@ -133,12 +133,12 @@ describe("torus utils mainnet", function () { expect(result3.metadata.typeOfUser).to.equal("v2"); expect(result3).eql({ oAuthKeyData: { - evmAddress: "0x61E52B6e488EC3dD6FDc0F5ed04a62Bb9c6BeF53", + walletAddress: "0x61E52B6e488EC3dD6FDc0F5ed04a62Bb9c6BeF53", X: "c01282dd68d2341031a1cff06f70d821cad45140f425f1c25055a8aa64959df8", Y: "cb3937773bb819d60b780b6d4c2edcf27c0f7090ba1fc2ff42504a8138a8e2d7", }, finalKeyData: { - evmAddress: "0x40A4A04fDa1f29a3667152C8830112FBd6A77BDD", + walletAddress: "0x40A4A04fDa1f29a3667152C8830112FBd6A77BDD", X: "6779af3031d9e9eec6b4133b0ae13e367c83a614f92d2008e10c7f3b8e6723bc", Y: "80edc4502abdfb220dd6e2fcfa2dbb058125dc95873e4bfa6877f9c26da7fdff", }, @@ -162,10 +162,10 @@ describe("torus utils mainnet", function () { const verifierDetails = { verifier, verifierId: email }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const { finalKeyData, oAuthKeyData, metadata } = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(finalKeyData.evmAddress).to.not.equal(""); - expect(finalKeyData.evmAddress).to.not.equal(null); - expect(oAuthKeyData.evmAddress).to.not.equal(""); - expect(oAuthKeyData.evmAddress).to.not.equal(null); + expect(finalKeyData.walletAddress).to.not.equal(""); + expect(finalKeyData.walletAddress).to.not.equal(null); + expect(oAuthKeyData.walletAddress).to.not.equal(""); + expect(oAuthKeyData.walletAddress).to.not.equal(null); expect(metadata.typeOfUser).to.equal("v1"); expect(metadata.upgraded).to.equal(false); // TorusUtils.enableLogging(false); @@ -174,8 +174,10 @@ describe("torus utils mainnet", function () { it("should be able to login", async function () { const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const result = await torus.retrieveShares(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const result = await torus.retrieveShares( + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, torusNodePub) + ); delete result.sessionData; expect(result.metadata.serverTimeOffset).lessThan(20); @@ -183,13 +185,18 @@ describe("torus utils mainnet", function () { expect(result).eql({ finalKeyData: { - evmAddress: "0x90A926b698047b4A87265ba1E9D8b512E8489067", + walletAddress: "0x90A926b698047b4A87265ba1E9D8b512E8489067", X: "a92d8bf1f01ad62e189a5cb0f606b89aa6df1b867128438c38e3209f3b9fc34f", Y: "0ad1ffaecb2178b02a37c455975368be9b967ead1b281202cc8d48c77618bff1", privKey: "0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44", }, oAuthKeyData: { - evmAddress: "0x90A926b698047b4A87265ba1E9D8b512E8489067", + walletAddress: "0x90A926b698047b4A87265ba1E9D8b512E8489067", + X: "a92d8bf1f01ad62e189a5cb0f606b89aa6df1b867128438c38e3209f3b9fc34f", + Y: "0ad1ffaecb2178b02a37c455975368be9b967ead1b281202cc8d48c77618bff1", + privKey: "0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44", + }, + postboxKeyData: { X: "a92d8bf1f01ad62e189a5cb0f606b89aa6df1b867128438c38e3209f3b9fc34f", Y: "0ad1ffaecb2178b02a37c455975368be9b967ead1b281202cc8d48c77618bff1", privKey: "0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44", @@ -203,20 +210,23 @@ describe("torus utils mainnet", function () { const idToken = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const hashedIdToken = keccak256(Buffer.from(idToken, "utf8")); const verifierDetails = { verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: TORUS_TEST_EMAIL, - }, - hashedIdToken.substring(2) + getRetrieveSharesParams( + torusNodeEndpoints, + torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: TORUS_TEST_EMAIL, + }, + hashedIdToken.substring(2), + torusNodePub + ) ); - expect(result.oAuthKeyData.evmAddress).to.be.equal("0x621a4d458cFd345dAE831D9E756F10cC40A50381"); - expect(result.finalKeyData.evmAddress).to.be.equal("0x621a4d458cFd345dAE831D9E756F10cC40A50381"); + expect(result.oAuthKeyData.walletAddress).to.be.equal("0x621a4d458cFd345dAE831D9E756F10cC40A50381"); + expect(result.finalKeyData.walletAddress).to.be.equal("0x621a4d458cFd345dAE831D9E756F10cC40A50381"); delete result.sessionData; expect(result.metadata.serverTimeOffset).lessThan(20); @@ -224,13 +234,18 @@ describe("torus utils mainnet", function () { expect(result).eql({ finalKeyData: { - evmAddress: "0x621a4d458cFd345dAE831D9E756F10cC40A50381", + walletAddress: "0x621a4d458cFd345dAE831D9E756F10cC40A50381", X: "52abc69ebec21deacd273dbdcb4d40066b701177bba906a187676e3292e1e236", Y: "5e57e251db2c95c874f7ec852439302a62ef9592c8c50024e3d48018a6f77c7e", privKey: "f55d89088a0c491d797c00da5b2ed6dc9c269c960ff121e45f255d06a91c6534", }, oAuthKeyData: { - evmAddress: "0x621a4d458cFd345dAE831D9E756F10cC40A50381", + walletAddress: "0x621a4d458cFd345dAE831D9E756F10cC40A50381", + X: "52abc69ebec21deacd273dbdcb4d40066b701177bba906a187676e3292e1e236", + Y: "5e57e251db2c95c874f7ec852439302a62ef9592c8c50024e3d48018a6f77c7e", + privKey: "f55d89088a0c491d797c00da5b2ed6dc9c269c960ff121e45f255d06a91c6534", + }, + postboxKeyData: { X: "52abc69ebec21deacd273dbdcb4d40066b701177bba906a187676e3292e1e236", Y: "5e57e251db2c95c874f7ec852439302a62ef9592c8c50024e3d48018a6f77c7e", privKey: "f55d89088a0c491d797c00da5b2ed6dc9c269c960ff121e45f255d06a91c6534", diff --git a/test/onekey.test.ts b/test/onekey.test.ts index 8940bfb..e8a9a1a 100644 --- a/test/onekey.test.ts +++ b/test/onekey.test.ts @@ -6,7 +6,7 @@ import faker from "faker"; import { keccak256, TorusPublicKey } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken } from "./helpers"; +import { generateIdToken, getRetrieveSharesParams } from "./helpers"; const TORUS_NODE_MANAGER = new NodeDetailManager({ network: TORUS_LEGACY_NETWORK.TESTNET, @@ -31,19 +31,19 @@ describe("torus onekey", function () { const verifierDetails = { verifier, verifierId: "himanshu@tor.us" }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const publicAddress = (await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails)) as TorusPublicKey; - expect(publicAddress.finalKeyData.evmAddress).to.be.equal("0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1"); + expect(publicAddress.finalKeyData.walletAddress).to.be.equal("0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1"); expect(publicAddress.metadata.serverTimeOffset).lessThan(20); delete publicAddress.metadata.serverTimeOffset; expect(publicAddress).eql({ oAuthKeyData: { - evmAddress: "0xf1e76fcDD28b5AA06De01de508fF21589aB9017E", + walletAddress: "0xf1e76fcDD28b5AA06De01de508fF21589aB9017E", X: "b3f2b4d8b746353fe670e0c39ac9adb58056d4d7b718d06b623612d4ec49268b", Y: "ac9f79dff78add39cdba380dbbf517c20cf2c1e06b32842a90a84a31f6eb9a9a", }, finalKeyData: { - evmAddress: "0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1", + walletAddress: "0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1", X: "12f6b90d66bda29807cf9ff14b2e537c25080154fc4fafed446306e8356ff425", Y: "e7c92e164b83e1b53e41e5d87d478bb07d7b19d105143e426e1ef08f7b37f224", }, @@ -60,13 +60,9 @@ describe("torus onekey", function () { it("should still login v1 account correctly", async function () { const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const retrieveSharesResponse = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, torusNodePub) ); expect(retrieveSharesResponse.metadata.serverTimeOffset).lessThan(20); @@ -75,13 +71,18 @@ describe("torus onekey", function () { expect(retrieveSharesResponse.finalKeyData.privKey).to.be.equal("296045a5599afefda7afbdd1bf236358baff580a0fe2db62ae5c1bbe817fbae4"); expect(retrieveSharesResponse).eql({ finalKeyData: { - evmAddress: "0x53010055542cCc0f2b6715a5c53838eC4aC96EF7", + walletAddress: "0x53010055542cCc0f2b6715a5c53838eC4aC96EF7", X: "3fa78a0bfb9ec48810bf1ee332360def2600c4aef528ff8b1e49a0d304722c91", Y: "46aaca39fc00c0f88f63a79989697c70eeeeec6489300c493dd07a5608ded0d4", privKey: "296045a5599afefda7afbdd1bf236358baff580a0fe2db62ae5c1bbe817fbae4", }, oAuthKeyData: { - evmAddress: "0xEfd7eDAebD0D99D1B7C8424b54835457dD005Dc4", + walletAddress: "0xEfd7eDAebD0D99D1B7C8424b54835457dD005Dc4", + X: "18409385c38e9729eb6b7837dc8f234256233ffab1ed7eeb1c23b230333396b4", + Y: "17d35ffc722d7a8dd88353815e9553cacf567c5f3b8d082adac9d653367ce47a", + privKey: "068ee4f97468ef1ae95d18554458d372e31968190ae38e377be59d8b3c9f7a25", + }, + postboxKeyData: { X: "18409385c38e9729eb6b7837dc8f234256233ffab1ed7eeb1c23b230333396b4", Y: "17d35ffc722d7a8dd88353815e9553cacf567c5f3b8d082adac9d653367ce47a", privKey: "068ee4f97468ef1ae95d18554458d372e31968190ae38e377be59d8b3c9f7a25", @@ -107,32 +108,40 @@ describe("torus onekey", function () { const idToken = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const hashedIdToken = keccak256(Buffer.from(idToken, "utf8")); const verifierDetails = { verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const retrieveSharesResponse = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: TORUS_TEST_EMAIL, - }, - hashedIdToken.substring(2) + getRetrieveSharesParams( + torusNodeEndpoints, + torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: TORUS_TEST_EMAIL, + }, + hashedIdToken.substring(2), + torusNodePub + ) ); expect(retrieveSharesResponse.metadata.serverTimeOffset).lessThan(20); delete retrieveSharesResponse.metadata.serverTimeOffset; - expect(retrieveSharesResponse.finalKeyData.evmAddress).to.be.equal("0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B"); + expect(retrieveSharesResponse.finalKeyData.walletAddress).to.be.equal("0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B"); expect(retrieveSharesResponse).eql({ finalKeyData: { - evmAddress: "0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B", + walletAddress: "0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B", X: "78658b2671f1bd6a488baf2afb8ce6f8d8b9a1a70842130b3c8756a9d51d9723", Y: "2e5840f47d645afa4bfe93c3715e65974051080d7a1e474eef8d68752924f4fb", privKey: "ad47959db4cb2e63e641bac285df1b944f54d1a1cecdaeea40042b60d53c35d2", }, oAuthKeyData: { - evmAddress: "0x5a165d2Ed4976BD104caDE1b2948a93B72FA91D2", + walletAddress: "0x5a165d2Ed4976BD104caDE1b2948a93B72FA91D2", + X: "aba2b085ae6390b3eb26802c3239bb7e3b9ed8ea6e1dcc28aeb67432571f20fc", + Y: "f1a2163cba5620b7b40241a6112e7918e9445b0b9cfbbb9d77b2de6f61ed5c27", + privKey: "d9733fc1098151f3e3289673e7c69c4ed46cbbdbc13416560e14741524d2d51a", + }, + postboxKeyData: { X: "aba2b085ae6390b3eb26802c3239bb7e3b9ed8ea6e1dcc28aeb67432571f20fc", Y: "f1a2163cba5620b7b40241a6112e7918e9445b0b9cfbbb9d77b2de6f61ed5c27", privKey: "d9733fc1098151f3e3289673e7c69c4ed46cbbdbc13416560e14741524d2d51a", @@ -162,52 +171,62 @@ describe("torus onekey", function () { const publicAddress = (await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails)) as TorusPublicKey; expect(publicAddress.metadata.typeOfUser).to.equal("v2"); expect(publicAddress.metadata.upgraded).to.equal(false); - expect(publicAddress.finalKeyData.evmAddress).to.not.equal(""); - expect(publicAddress.finalKeyData.evmAddress).to.not.equal(null); - expect(publicAddress.oAuthKeyData.evmAddress).to.not.equal(""); - expect(publicAddress.oAuthKeyData.evmAddress).to.not.equal(null); + expect(publicAddress.finalKeyData.walletAddress).to.not.equal(""); + expect(publicAddress.finalKeyData.walletAddress).to.not.equal(null); + expect(publicAddress.oAuthKeyData.walletAddress).to.not.equal(""); + expect(publicAddress.oAuthKeyData.walletAddress).to.not.equal(null); }); it("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 }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const result = await torus.retrieveShares(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: email }, token); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const result = await torus.retrieveShares( + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: email }, token, torusNodePub) + ); expect(!result.metadata.nonce.eq(new BN("0"))); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.upgraded).to.equal(false); - expect(result.finalKeyData.evmAddress).to.not.equal(""); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(""); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(""); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(""); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); }); it("should still login v2 account correctly", async function () { const token = generateIdToken("Jonathan.Nolan@hotmail.com", "ES256"); const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: "Jonathan.Nolan@hotmail.com" }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const retrieveSharesResponse = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: "Jonathan.Nolan@hotmail.com" }, - token + getRetrieveSharesParams( + torusNodeEndpoints, + torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: "Jonathan.Nolan@hotmail.com" }, + token, + torusNodePub + ) ); expect(retrieveSharesResponse.metadata.serverTimeOffset).lessThan(20); delete retrieveSharesResponse.metadata.serverTimeOffset; expect(retrieveSharesResponse.finalKeyData.privKey).to.be.equal("9ec5b0504e252e35218c7ce1e4660eac190a1505abfbec7102946f92ed750075"); - expect(retrieveSharesResponse.finalKeyData.evmAddress).to.be.equal("0x2876820fd9536BD5dd874189A85d71eE8bDf64c2"); + expect(retrieveSharesResponse.finalKeyData.walletAddress).to.be.equal("0x2876820fd9536BD5dd874189A85d71eE8bDf64c2"); expect(retrieveSharesResponse).eql({ finalKeyData: { - evmAddress: "0x2876820fd9536BD5dd874189A85d71eE8bDf64c2", + walletAddress: "0x2876820fd9536BD5dd874189A85d71eE8bDf64c2", X: "ad4c223520aac9bc3ec72399869601fd59f29363471131914e2ed2bc4ba46e54", Y: "802c6e40b22b49b5ef73fa49b194c2037267215fa01683aa86746907aab37ae1", privKey: "9ec5b0504e252e35218c7ce1e4660eac190a1505abfbec7102946f92ed750075", }, oAuthKeyData: { - evmAddress: "0x54de3Df0CA76AAe3e171FB410F0626Ab759f3c24", + walletAddress: "0x54de3Df0CA76AAe3e171FB410F0626Ab759f3c24", + X: "49d69b8550bb0eba77595c73bf57f0463ff96adf6b50d44f9e1bcf2b3fb7976e", + Y: "d63bac65bdfc7484a28d4362347bbd098095db190c14a4ce9dbaafe74803eccc", + privKey: "f4b7e0fb1e6f6fbac539c55e22aff2900947de652d2d6254a9cd8709f505f83a", + }, + postboxKeyData: { X: "49d69b8550bb0eba77595c73bf57f0463ff96adf6b50d44f9e1bcf2b3fb7976e", Y: "d63bac65bdfc7484a28d4362347bbd098095db190c14a4ce9dbaafe74803eccc", privKey: "f4b7e0fb1e6f6fbac539c55e22aff2900947de652d2d6254a9cd8709f505f83a", diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index bad0b9e..751e8ad 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -1,13 +1,13 @@ import { TORUS_LEGACY_NETWORK, TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; -import { generatePrivate } from "@toruslabs/eccrypto"; import { NodeDetailManager } from "@toruslabs/fetch-node-details"; import BN from "bn.js"; import { expect } from "chai"; +import { ec as EC } from "elliptic"; import faker from "faker"; -import { keccak256 } from "../src"; +import { generatePrivateKey, keccak256 } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken, lookupVerifier } from "./helpers"; +import { generateIdToken, getImportKeyParams, getRetrieveSharesParams, lookupVerifier } from "./helpers"; const TORUS_TEST_EMAIL = "devnettestuser@tor.us"; const TORUS_HASH_ENABLED_TEST_EMAIL = "saasas@tr.us"; @@ -51,16 +51,16 @@ describe("torus utils sapphire devnet", function () { const { torusNodeSSSEndpoints: torusNodeEndpoints, torusNodePub } = await LEGACY_TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const publicKeyData = await legacyTorus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); expect(publicKeyData.metadata.typeOfUser).to.equal("v1"); - expect(publicKeyData.finalKeyData.evmAddress).to.equal("0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1"); + expect(publicKeyData.finalKeyData.walletAddress).to.equal("0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1"); delete publicKeyData.metadata.serverTimeOffset; expect(publicKeyData).eql({ oAuthKeyData: { - evmAddress: "0xf1e76fcDD28b5AA06De01de508fF21589aB9017E", + walletAddress: "0xf1e76fcDD28b5AA06De01de508fF21589aB9017E", X: "b3f2b4d8b746353fe670e0c39ac9adb58056d4d7b718d06b623612d4ec49268b", Y: "ac9f79dff78add39cdba380dbbf517c20cf2c1e06b32842a90a84a31f6eb9a9a", }, finalKeyData: { - evmAddress: "0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1", + walletAddress: "0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1", X: "12f6b90d66bda29807cf9ff14b2e537c25080154fc4fafed446306e8356ff425", Y: "e7c92e164b83e1b53e41e5d87d478bb07d7b19d105143e426e1ef08f7b37f224", }, @@ -88,13 +88,9 @@ describe("torus utils sapphire devnet", function () { network: TORUS_LEGACY_NETWORK.TESTNET, clientId: "YOUR_CLIENT_ID", }); - const { torusNodeSSSEndpoints: torusNodeEndpoints, torusIndexes } = await LEGACY_TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const { torusNodeSSSEndpoints: torusNodeEndpoints, torusIndexes, torusNodePub } = await LEGACY_TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const retrieveSharesResponse = await legacyTorus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: email }, - token + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: email }, token, torusNodePub) ); expect(retrieveSharesResponse.finalKeyData.privKey).to.be.equal("dca7f29d234dc71561efe1a874d872bf34f6528bc042fe35e57197eac1f14eb9"); delete retrieveSharesResponse.sessionData; @@ -102,13 +98,18 @@ describe("torus utils sapphire devnet", function () { expect(retrieveSharesResponse).eql({ oAuthKeyData: { - evmAddress: "0xbeFfcC367D741C53A63F50eA805c1e93d3C64fEc", + walletAddress: "0xbeFfcC367D741C53A63F50eA805c1e93d3C64fEc", + X: "2b1c47c8fbca61ee7f82a8aff53a357f6b66af0dffbef6a3e3ac649180616e51", + Y: "fef450a5263f7c57605dd439225faee830943cb484e8dfe1f3c82c3d538f61af", + privKey: "dca7f29d234dc71561efe1a874d872bf34f6528bc042fe35e57197eac1f14eb9", + }, + postboxKeyData: { X: "2b1c47c8fbca61ee7f82a8aff53a357f6b66af0dffbef6a3e3ac649180616e51", Y: "fef450a5263f7c57605dd439225faee830943cb484e8dfe1f3c82c3d538f61af", privKey: "dca7f29d234dc71561efe1a874d872bf34f6528bc042fe35e57197eac1f14eb9", }, finalKeyData: { - evmAddress: "0xbeFfcC367D741C53A63F50eA805c1e93d3C64fEc", + walletAddress: "0xbeFfcC367D741C53A63F50eA805c1e93d3C64fEc", X: "2b1c47c8fbca61ee7f82a8aff53a357f6b66af0dffbef6a3e3ac649180616e51", Y: "fef450a5263f7c57605dd439225faee830943cb484e8dfe1f3c82c3d538f61af", privKey: "dca7f29d234dc71561efe1a874d872bf34f6528bc042fe35e57197eac1f14eb9", @@ -144,19 +145,19 @@ describe("torus utils sapphire devnet", function () { verifier: v2Verifier, verifierId: v2TestEmail, }); - expect(result.finalKeyData.evmAddress).to.equal("0xE91200d82029603d73d6E307DbCbd9A7D0129d8D"); + expect(result.finalKeyData.walletAddress).to.equal("0xE91200d82029603d73d6E307DbCbd9A7D0129d8D"); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0x376597141d8d219553378313d18590F373B09795", + walletAddress: "0x376597141d8d219553378313d18590F373B09795", X: "86cd2db15b7a9937fa8ab7d0bf8e7f4113b64d1f4b2397aad35d6d4749d2fb6c", Y: "86ef47a3724144331c31a3a322d85b6fc1a5d113b41eaa0052053b6e3c74a3e2", }, finalKeyData: { - evmAddress: "0xE91200d82029603d73d6E307DbCbd9A7D0129d8D", + walletAddress: "0xE91200d82029603d73d6E307DbCbd9A7D0129d8D", X: "c350e338dde24df986915992fea6e0aef3560c245ca144ee7fe1498784c4ef4e", Y: "a605e52b65d3635f89654519dfa7e31f7b45f206ef4189866ad0c2240d40f97f", }, @@ -179,18 +180,18 @@ describe("torus utils sapphire devnet", function () { verifierId: v2nTestEmail, }); expect(data.metadata.typeOfUser).to.equal("v2"); - expect(data.finalKeyData.evmAddress).to.equal("0x1016DA7c47A04C76036637Ea02AcF1d29c64a456"); + expect(data.finalKeyData.walletAddress).to.equal("0x1016DA7c47A04C76036637Ea02AcF1d29c64a456"); expect(data.metadata.serverTimeOffset).lessThan(20); delete data.metadata.serverTimeOffset; expect(data).eql({ oAuthKeyData: { - evmAddress: "0xd45383fbF04BccFa0450d7d8ee453ca86b7C6544", + walletAddress: "0xd45383fbF04BccFa0450d7d8ee453ca86b7C6544", X: "d25cc473fbb448d20b5551f3c9aa121e1924b3d197353347187c47ad13ecd5d8", Y: "3394000f43160a925e6c3017dde1354ecb2b61739571c6584f58edd6b923b0f5", }, finalKeyData: { - evmAddress: "0x1016DA7c47A04C76036637Ea02AcF1d29c64a456", + walletAddress: "0x1016DA7c47A04C76036637Ea02AcF1d29c64a456", X: "d3e222f6b23f0436b7c86e9cc4164eb5ea8448e4c0e7539c8b4f7fd00e8ec5c7", Y: "1c47f5faccec6cf57c36919f6f0941fe3d8d65033cf2cc78f209304386044222", }, @@ -217,12 +218,12 @@ describe("torus utils sapphire devnet", function () { expect(result).eql({ oAuthKeyData: { - evmAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + walletAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", }, finalKeyData: { - evmAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", + walletAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", }, @@ -244,11 +245,11 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.finalKeyData.evmAddress).to.not.equal(""); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(""); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(""); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(""); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.upgraded).to.equal(false); }); @@ -282,12 +283,12 @@ describe("torus utils sapphire devnet", function () { expect(result).eql({ oAuthKeyData: { - evmAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + walletAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", }, finalKeyData: { - evmAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", + walletAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", }, @@ -310,8 +311,8 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.not.equal(""); - expect(result.finalKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(""); + expect(result.finalKeyData.walletAddress).to.not.equal(null); }); it("should be able to login", async function () { @@ -319,24 +320,32 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: TORUS_TEST_EMAIL }, + token, + nodeDetails.torusNodePub + ) ); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ finalKeyData: { - evmAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", + walletAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", privKey: "230dad9f42039569e891e6b066ff5258b14e9764ef5176d74aeb594d1a744203", }, oAuthKeyData: { - evmAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + walletAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", + Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", + privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", + }, + postboxKeyData: { X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", @@ -358,29 +367,84 @@ describe("torus utils sapphire devnet", function () { }); }); + it("should be able to login with non dkg keys", async function () { + const email = `atomicimporttest2`; + const token = generateIdToken(email, "ES256"); + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.retrieveShares( + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + nodeDetails.torusNodePub, + {}, + false + ) + ); + + const publicResult = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result.finalKeyData.X).eql(publicResult.finalKeyData.X); + }); + + it("should be able to login a new user with non dkg keys", async function () { + const email = `${faker.internet.email()}`; + const token = generateIdToken(email, "ES256"); + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.retrieveShares( + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + nodeDetails.torusNodePub, + {}, + false + ) + ); + + const publicResult = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + + expect(result.finalKeyData.X).eql(publicResult.finalKeyData.X); + }); + it("should be able to login even when node is down", async function () { 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; torusNodeEndpoints[1] = "https://example.com"; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: TORUS_TEST_EMAIL }, + token, + nodeDetails.torusNodePub + ) ); delete result.metadata.serverTimeOffset; expect(result).eql({ finalKeyData: { - evmAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", + walletAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", privKey: "230dad9f42039569e891e6b066ff5258b14e9764ef5176d74aeb594d1a744203", }, oAuthKeyData: { - evmAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + walletAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", + Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", + privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", + }, + postboxKeyData: { X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", @@ -413,11 +477,14 @@ describe("torus utils sapphire devnet", function () { TorusUtils.setSessionTime(customSessionTime); // 1hr const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: TORUS_TEST_EMAIL }, + token, + nodeDetails.torusNodePub + ) ); const signatures = result.sessionData.sessionTokenData.map((s) => ({ data: s.token, sig: s.signature })); @@ -430,26 +497,28 @@ describe("torus utils sapphire devnet", function () { }); }); - it.skip("should be able to import a key for a new user", async function () { + it("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(); + const ec = new EC("secp256k1"); + const privKeyBuffer = generatePrivateKey(ec, Buffer); const privHex = privKeyBuffer.toString("hex"); const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: email }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.importPrivateKey( - torusNodeEndpoints, - nodeDetails.torusIndexes, - nodeDetails.torusNodePub, - TORUS_TEST_VERIFIER, - { verifier_id: email }, - token, - privHex + getImportKeyParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + nodeDetails.torusNodePub, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + privHex + ) ); expect(result.finalKeyData.privKey).to.be.equal(privHex); const result1 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { verifier: TORUS_TEST_VERIFIER, verifierId: email }); - expect(result1.finalKeyData.evmAddress).to.be.equal(result.finalKeyData.evmAddress); + expect(result1.finalKeyData.walletAddress).to.be.equal(result.finalKeyData.walletAddress); }); it("should fetch pub address of tss verifier id", async function () { @@ -466,12 +535,12 @@ describe("torus utils sapphire devnet", function () { expect(result).eql({ oAuthKeyData: { - evmAddress: "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30", + walletAddress: "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30", X: "d45d4ad45ec643f9eccd9090c0a2c753b1c991e361388e769c0dfa90c210348c", Y: "fdc151b136aa7df94e97cc7d7007e2b45873c4b0656147ec70aad46e178bce1e", }, finalKeyData: { - evmAddress: "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30", + walletAddress: "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30", X: "d45d4ad45ec643f9eccd9090c0a2c753b1c991e361388e769c0dfa90c210348c", Y: "fdc151b136aa7df94e97cc7d7007e2b45873c4b0656147ec70aad46e178bce1e", }, @@ -494,8 +563,8 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.eql(new BN("0")); expect(result.metadata.upgraded).to.equal(false); @@ -510,14 +579,17 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifierId: email, verifier: TORUS_TEST_VERIFIER }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { extended_verifier_id: tssVerifierId, verifier_id: email }, - token + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { extended_verifier_id: tssVerifierId, verifier_id: email }, + token, + nodeDetails.torusNodePub + ) ); expect(result.finalKeyData.privKey).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.eql(new BN("0")); expect(result.metadata.upgraded).to.equal(true); @@ -528,18 +600,18 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0xF79b5ffA48463eba839ee9C97D61c6063a96DA03"); + expect(result.finalKeyData.walletAddress).to.equal("0xF79b5ffA48463eba839ee9C97D61c6063a96DA03"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", + walletAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", X: "9c591943683c0e5675f99626cea84153a3c5b72c6e7840f8b8b53d0f2bb50c67", Y: "9d9896d82e565a2d5d437745af6e4560f3564c2ac0d0edcb72e0b508b3ac05a0", }, finalKeyData: { - evmAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", + walletAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", X: "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a", Y: "575b7a4d0ef9921b3b1b84f30d412e87bc69b4eab83f6706e247cceb9e985a1e", }, @@ -574,19 +646,19 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0xF79b5ffA48463eba839ee9C97D61c6063a96DA03"); + expect(result.finalKeyData.walletAddress).to.equal("0xF79b5ffA48463eba839ee9C97D61c6063a96DA03"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", + walletAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", X: "9c591943683c0e5675f99626cea84153a3c5b72c6e7840f8b8b53d0f2bb50c67", Y: "9d9896d82e565a2d5d437745af6e4560f3564c2ac0d0edcb72e0b508b3ac05a0", }, finalKeyData: { - evmAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", + walletAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", X: "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a", Y: "575b7a4d0ef9921b3b1b84f30d412e87bc69b4eab83f6706e247cceb9e985a1e", }, @@ -610,24 +682,32 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - HashEnabledVerifier, - { verifier_id: TORUS_HASH_ENABLED_TEST_EMAIL }, - token + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + HashEnabledVerifier, + { verifier_id: TORUS_HASH_ENABLED_TEST_EMAIL }, + token, + nodeDetails.torusNodePub + ) ); delete result.metadata.serverTimeOffset; expect(result.finalKeyData.privKey).to.be.equal("066270dfa345d3d0415c8223e045f366b238b50870de7e9658e3c6608a7e2d32"); expect(result).eql({ finalKeyData: { - evmAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", + walletAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", X: "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a", Y: "575b7a4d0ef9921b3b1b84f30d412e87bc69b4eab83f6706e247cceb9e985a1e", privKey: "066270dfa345d3d0415c8223e045f366b238b50870de7e9658e3c6608a7e2d32", }, oAuthKeyData: { - evmAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", + walletAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", + X: "9c591943683c0e5675f99626cea84153a3c5b72c6e7840f8b8b53d0f2bb50c67", + Y: "9d9896d82e565a2d5d437745af6e4560f3564c2ac0d0edcb72e0b508b3ac05a0", + privKey: "b47769e81328794adf3534e58d02803ca2a5e4588db81780f5bf679c77988946", + }, + postboxKeyData: { X: "9c591943683c0e5675f99626cea84153a3c5b72c6e7840f8b8b53d0f2bb50c67", Y: "9d9896d82e565a2d5d437745af6e4560f3564c2ac0d0edcb72e0b508b3ac05a0", privKey: "b47769e81328794adf3534e58d02803ca2a5e4588db81780f5bf679c77988946", @@ -658,22 +738,25 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: email, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: email, - }, - hashedIdToken.substring(2) + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: email, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: email, + }, + hashedIdToken.substring(2), + nodeDetails.torusNodePub + ) ); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.finalKeyData.evmAddress).to.not.equal(""); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(""); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.not.equal(null); expect(result.metadata.upgraded).to.equal(false); diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts new file mode 100644 index 0000000..c8021a7 --- /dev/null +++ b/test/sapphire_devnet_ed25519.test.ts @@ -0,0 +1,453 @@ +import { TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; +import { NodeDetailManager } from "@toruslabs/fetch-node-details"; +import BN from "bn.js"; +import base58 from "bs58"; +import { expect } from "chai"; +import faker from "faker"; + +import { keccak256 } from "../src"; +import TorusUtils from "../src/torus"; +import { generateIdToken, getImportKeyParams, getRetrieveSharesParams, lookupVerifier } from "./helpers"; + +const TORUS_TEST_EMAIL = "ed25519testuser@tor.us"; +const TORUS_TEST_EMAIL_HASHED = "ed25519testuserhashed19@tor.us"; + +const TORUS_EXTENDED_VERIFIER_EMAIL = "testextenderverifierided25519@example.com"; + +const TORUS_TEST_VERIFIER = "torus-test-health"; + +const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; +const HashEnabledVerifier = "torus-test-verifierid-hash"; + +describe("torus utils ed25519 sapphire devnet", function () { + let torus: TorusUtils; + let TORUS_NODE_MANAGER: NodeDetailManager; + + beforeEach("one time execution before all tests", async function () { + TORUS_NODE_MANAGER = new NodeDetailManager({ network: TORUS_SAPPHIRE_NETWORK.SAPPHIRE_DEVNET }); + torus = new TorusUtils({ + network: TORUS_SAPPHIRE_NETWORK.SAPPHIRE_DEVNET, + clientId: "YOUR_CLIENT_ID", + enableOneKey: true, + keyType: "ed25519", + }); + TorusUtils.enableLogging(false); + }); + + it("should should fetch public address", async function () { + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: "Willa_Funk11@gmail.com" }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result.finalKeyData.walletAddress).eql("HHmiJMCAwhyf9ZWNtj7FEKGXeeC2NjUjPobpDKm43yKs"); + delete result.metadata.serverTimeOffset; + expect(result).eql({ + oAuthKeyData: { + walletAddress: "49yLu8yLqpuCXchzjQSt1tpBz8AP2E9EzzP7a8QtxmTE", + X: "5d39eba90fafbce150b33b9a60b41e1cfdf9e2640b55bf96b787173d74f8e415", + Y: "099639b7da35c1f31a44da7399a29d7db8eaa9639582cf7ed80aa4f7216adf2e", + }, + finalKeyData: { + walletAddress: "HHmiJMCAwhyf9ZWNtj7FEKGXeeC2NjUjPobpDKm43yKs", + X: "575203523b34bcfa2c25c428871c421afd69dbcb7375833b52ef264aaa466a81", + Y: "26f0b1f5740088c2ecf676081b8e2fe5254f1cbb693947ae391af13500d706f2", + }, + metadata: { + pubNonce: { + X: "71bf997547c1ac3f0babee87ebac055e8542863ebb1ba66e8092499eacbffd22", + Y: "71a0a70c5ae06d7eeb45673d4081fdfc9f29c4acfbbb57bf52a33dd7630599b1", + }, + nonce: new BN("0", "hex"), + typeOfUser: "v2", + upgraded: false, + }, + nodesData: result.nodesData, + }); + }); + + it("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 = new BN(generatePrivateKey(ec, Buffer)); + // key exported from phantom wallet + const privB58 = "BjremmcjdFWexYJWcNSsT3U8ekuq6KnenBCSvxVfx2fQuvWbZQzDtQuAuXtQzcgxNY9CRyVNXJu2W5Rgt7ufQDh"; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: email }); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + + const decodedKey = Buffer.from(base58.decode(privB58)); + const seedKey = decodedKey.subarray(0, 32).toString("hex"); + const result = await torus.importPrivateKey( + getImportKeyParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + nodeDetails.torusNodePub, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + seedKey + ) + ); + expect(result.finalKeyData.walletAddress).eql("3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM"); + expect(result.finalKeyData.privKey).to.be.equal(seedKey); + + const token1 = generateIdToken(email, "ES256"); + const result1 = await torus.retrieveShares( + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token1, + nodeDetails.torusNodePub + ) + ); + expect(result1.finalKeyData.walletAddress).eql("3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM"); + expect(result.finalKeyData.privKey).to.be.equal(seedKey); + + const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { + verifier: TORUS_TEST_VERIFIER, + verifierId: email, + }); + expect(result2.finalKeyData.walletAddress).eql("3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM"); + }); + + it("should be able to login", async function () { + const testEmail = "edd2519TestUser951@example.com"; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: testEmail }); + + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + + const token = generateIdToken(`${testEmail}`, "ES256"); + const result = await torus.retrieveShares( + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: testEmail }, + token, + nodeDetails.torusNodePub + ) + ); + + delete result.metadata.serverTimeOffset; + delete result.sessionData; + expect(result).eql({ + oAuthKeyData: { + walletAddress: "HV19ETHePfCtZK55Bo5znHXLfd46nu4AQbjtbYumY7ea", + X: "1f5f95f5af0a67b4af731608fdb26115efcb011dcf64a355bf2442e4ec058ae0", + Y: "33f3317a574a5444b78aecc56dd894a56d1fbb90134bc7c63d0f9d11f969e7f4", + privKey: "07b1ff9ec97c93ac3d5125db8283ec0b22056623d0a9407a48c9def302db07b7", + }, + postboxKeyData: { + X: "a7fa19a07eb387e3b1a95843f7d56f8ca88d11c632c4f53b8554068876451d27", + Y: "6ddc5c79c28d197991ecf9304b4e66ecc2e98dcf3cb73ec3c79953bd87e4a6ff", + privKey: "fa5efb87dbdcea273654342d622fcbfa087f4a572caf76d2214e00a8732c6ddf", + }, + finalKeyData: { + walletAddress: "Dp6eiDQs7LbHLVATSEaA7NUm9DkEAZTXdzXy13vbYoq8", + X: "2cfc2713bd866494690b50d0cb1500878903130a0a1a31fae1ffa5f8cd436407", + Y: "775cc21e123af488ad2c1fd70b22f9427a0596691c991186d42e69fa08ee5cbe", + privKey: "cfe3a737880b01da41765e90466400512564bf3e12648e8e715ae54b53b1e11b", + }, + metadata: { + pubNonce: { + X: "78f007266e249301a241bcb72dba7d305f41f11a432dd8f4dec22c9a0035b3ac", + Y: "7e0545c176528910726ad528e12e1fa39e106ad06957e807a2660c9214596d33", + }, + nonce: new BN("58c39dd2c8dcdbd740b758623c88b9dfb36d6e3b590d073a1456c0268af8270", "hex"), + typeOfUser: "v2", + upgraded: false, + }, + nodesData: result.nodesData, + }); + const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { + verifier: TORUS_TEST_VERIFIER, + verifierId: testEmail, + }); + expect(result2.finalKeyData.walletAddress).eql(result.finalKeyData.walletAddress); + }); + + it("should be able to key assign", async function () { + const email = faker.internet.email(); + const token = generateIdToken(email, "ES256"); + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result.finalKeyData.walletAddress).to.not.equal(""); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + const result2 = await torus.retrieveShares( + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + nodeDetails.torusNodePub + ) + ); + expect(result.finalKeyData.walletAddress).to.equal(result2.finalKeyData.walletAddress); + }); + + it("should be able to login a new user with non dkg keys", async function () { + const email = `${faker.internet.email()}`; + const token = generateIdToken(email, "ES256"); + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.retrieveShares( + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + nodeDetails.torusNodePub, + {}, + false + ) + ); + + const publicResult = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + + expect(result.finalKeyData.X).eql(publicResult.finalKeyData.X); + }); + + it("should be able to login even when node is down", async function () { + 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; + torusNodeEndpoints[1] = "https://example.com"; + const result = await torus.retrieveShares( + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: TORUS_TEST_EMAIL }, + token, + nodeDetails.torusNodePub + ) + ); + expect(result.finalKeyData.privKey).to.be.equal("ea39cc89d2d8b8403858d1c518fe82e2500cc83e472ba86d006323b57835a519"); + }); + + it("should fetch pub address of tss verifier id", async function () { + const email = TORUS_EXTENDED_VERIFIER_EMAIL; + const nonce = 0; + const tssTag = "default"; + const tssVerifierId = `${email}\u0015${tssTag}\u0016${nonce}`; + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email, extendedVerifierId: tssVerifierId }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + delete result.metadata.serverTimeOffset; + expect(result).eql({ + oAuthKeyData: { + walletAddress: "8YXTwFuGWc15bYSw7npC9nJpZzg3yoQpYPDe81DuKjGZ", + X: "0a89d65e3ba433f52aa86c6b1b832501dea6200a178ec1d1f2a17d556b551cba", + Y: "7ed3af68be167f590faec6a951c920730b760dd8f11af6a708dde3cc80421570", + }, + finalKeyData: { + walletAddress: "8YXTwFuGWc15bYSw7npC9nJpZzg3yoQpYPDe81DuKjGZ", + X: "0a89d65e3ba433f52aa86c6b1b832501dea6200a178ec1d1f2a17d556b551cba", + Y: "7ed3af68be167f590faec6a951c920730b760dd8f11af6a708dde3cc80421570", + }, + metadata: { + pubNonce: undefined, + nonce: new BN("0"), + upgraded: false, + typeOfUser: "v2", + }, + nodesData: result.nodesData, + }); + }); + + it("should assign key to tss verifier id", async function () { + const email = faker.internet.email(); + const nonce = 0; + const tssTag = "default"; + const tssVerifierId = `${email}\u0015${tssTag}\u0016${nonce}`; + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email, extendedVerifierId: tssVerifierId }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); + expect(result.metadata.typeOfUser).to.equal("v2"); + expect(result.metadata.nonce).to.eql(new BN("0")); + expect(result.metadata.upgraded).to.equal(false); + }); + + it("should allow test tss verifier id to fetch shares", async function () { + const email = faker.internet.email(); + const nonce = 0; + const tssTag = "default"; + const tssVerifierId = `${email}\u0015${tssTag}\u0016${nonce}`; + const token = generateIdToken(email, "ES256"); + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifierId: email, verifier: TORUS_TEST_VERIFIER }); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.retrieveShares( + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { extended_verifier_id: tssVerifierId, verifier_id: email }, + token, + nodeDetails.torusNodePub + ) + ); + expect(result.finalKeyData.privKey).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); + expect(result.metadata.typeOfUser).to.equal("v2"); + expect(result.metadata.nonce).to.eql(new BN("0")); + expect(result.metadata.upgraded).to.equal(true); + const token2 = generateIdToken(email, "ES256"); + + const result2 = await torus.retrieveShares( + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { extended_verifier_id: tssVerifierId, verifier_id: email }, + token2, + nodeDetails.torusNodePub + ) + ); + expect(result.finalKeyData.privKey).to.equal(result2.finalKeyData.privKey); + expect(result.oAuthKeyData.walletAddress).to.equal(result2.finalKeyData.walletAddress); + expect(result2.metadata.typeOfUser).to.equal(result.metadata.typeOfUser); + expect(result2.metadata.upgraded).to.equal(result.metadata.upgraded); + + const result3 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { + verifier: TORUS_TEST_VERIFIER, + verifierId: email, + extendedVerifierId: tssVerifierId, + }); + expect(result3.oAuthKeyData.walletAddress).to.equal(result2.finalKeyData.walletAddress); + }); + + it("should fetch public address when verifierID hash enabled", async function () { + const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL_HASHED }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + delete result.metadata.serverTimeOffset; + + expect(result).eql({ + oAuthKeyData: { + walletAddress: "DybMLmBwiPqt8GXpDW2MwHi5ZqEtrbgxgwcf7shPdTWg", + X: "45c531429896ab89078789018b21639dab308b7d3952d9df243177e60fc0eb1f", + Y: "6155cf9bb00f8eedf398361c2140a5ed3fe2b3c51b883e757addcb06e09bcbc0", + }, + finalKeyData: { + walletAddress: "HK9Xo2UgjuMNxBi6WxX76hfQm9oTtJdDUSGKFhzGQiSo", + X: "6002549f42c1f3504652ce4b3fb1cbff4f1eaa1b66551313dd9c44d48b31a63d", + Y: "44af643f9200d11c5f60212de9470f92806df18eeea730a8736e4570611761f2", + }, + metadata: { + pubNonce: { + X: "4cc875975c4ed6fed34758eab0be8954c50decbe736f85b3c5011f5035dd9e27", + Y: "233fe212cf0d6033be989f9dd5ffd5dfe77f0c3340984fcc5b0dd745bdfded12", + }, + nonce: new BN("0", "hex"), + upgraded: false, + typeOfUser: "v2", + }, + nodesData: result.nodesData, + }); + }); + + it("should be able to login when verifierID hash enabled", async function () { + const testEmail = TORUS_TEST_EMAIL_HASHED; + const token = generateIdToken(testEmail, "ES256"); + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL_HASHED }); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.retrieveShares( + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + HashEnabledVerifier, + { verifier_id: TORUS_TEST_EMAIL_HASHED }, + token, + nodeDetails.torusNodePub + ) + ); + delete result.metadata.serverTimeOffset; + expect(result).eql({ + finalKeyData: { + walletAddress: "HK9Xo2UgjuMNxBi6WxX76hfQm9oTtJdDUSGKFhzGQiSo", + X: "6002549f42c1f3504652ce4b3fb1cbff4f1eaa1b66551313dd9c44d48b31a63d", + Y: "44af643f9200d11c5f60212de9470f92806df18eeea730a8736e4570611761f2", + privKey: "47c471c6c3b53f751e39feae967359b9258a790a30f2db394625f76b0c84ada0", + }, + postboxKeyData: { + X: "8a25dd3b35a77927e5f094b333ccd69a77acec89868db646e2afbf363f191b11", + Y: "aa9282b02c5af9d06d206631ac503c218f807f0365c0a8677f6347fd01f8ffb0", + privKey: "239c7b52e39074d8c580e3fcd2950dbd2562e8b54340d2628bac055546b6a97e", + }, + oAuthKeyData: { + walletAddress: "DybMLmBwiPqt8GXpDW2MwHi5ZqEtrbgxgwcf7shPdTWg", + X: "45c531429896ab89078789018b21639dab308b7d3952d9df243177e60fc0eb1f", + Y: "6155cf9bb00f8eedf398361c2140a5ed3fe2b3c51b883e757addcb06e09bcbc0", + privKey: "0423cd18b36b862054489ad706d9be0226204af69b0407907dc1f3ee9ca72b7a", + }, + sessionData: { + sessionTokenData: result.sessionData.sessionTokenData, + sessionAuthKey: result.sessionData.sessionAuthKey, + }, + metadata: { + pubNonce: { + X: "4cc875975c4ed6fed34758eab0be8954c50decbe736f85b3c5011f5035dd9e27", + Y: "233fe212cf0d6033be989f9dd5ffd5dfe77f0c3340984fcc5b0dd745bdfded12", + }, + nonce: new BN("8ff7137ce3f5648b8722779e0d3c153bf76042800783bd6793f38672d8c129d", "hex"), + typeOfUser: "v2", + upgraded: false, + }, + nodesData: result.nodesData, + }); + }); + + // to do: update pub keys + it.skip("should lookup return hash when verifierID hash enabled", async function () { + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: HashEnabledVerifier, verifierId: TORUS_TEST_VERIFIER }); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + for (const endpoint of torusNodeEndpoints) { + const pubKeyX = "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a"; + const pubKeyY = "575b7a4d0ef9921b3b1b84f30d412e87bc69b4eab83f6706e247cceb9e985a1e"; + const response = await lookupVerifier(endpoint, pubKeyX, pubKeyY); + const verifierID = response.result.verifiers[HashEnabledVerifier][0]; + expect(verifierID).to.equal("086c23ab78578f2fce9a1da11c0071ec7c2225adb1bf499ffaee98675bee29b7"); + } + }); + + it("should be able to aggregate login", async function () { + const email = faker.internet.email(); + const idToken = generateIdToken(email, "ES256"); + const hashedIdToken = keccak256(Buffer.from(idToken, "utf8")); + const verifierDetails = { verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: email }; + + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.retrieveShares( + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: email, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: email, + }, + hashedIdToken.substring(2), + nodeDetails.torusNodePub + ) + ); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(""); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); + expect(result.metadata.typeOfUser).to.equal("v2"); + expect(result.metadata.nonce).to.not.equal(null); + expect(result.metadata.upgraded).to.equal(false); + }); +}); diff --git a/test/sapphire_mainnet.test.ts b/test/sapphire_mainnet.test.ts index 1bc0340..0fdade6 100644 --- a/test/sapphire_mainnet.test.ts +++ b/test/sapphire_mainnet.test.ts @@ -1,13 +1,13 @@ import { TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; -import { generatePrivate } from "@toruslabs/eccrypto"; import { NodeDetailManager } from "@toruslabs/fetch-node-details"; import BN from "bn.js"; import { expect } from "chai"; +import { ec as EC } from "elliptic"; import faker from "faker"; -import { keccak256 } from "../src"; +import { generatePrivateKey, keccak256 } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken } from "./helpers"; +import { generateIdToken, getImportKeyParams, getRetrieveSharesParams } from "./helpers"; const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; @@ -33,18 +33,18 @@ describe("torus utils sapphire mainnet", function () { 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("0x327b2742768B436d09153429E762FADB54413Ded"); + expect(result.finalKeyData.walletAddress).to.equal("0x327b2742768B436d09153429E762FADB54413Ded"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0xb1a49C6E50a1fC961259a8c388EAf5953FA5152b", + walletAddress: "0xb1a49C6E50a1fC961259a8c388EAf5953FA5152b", X: "a9f5a463aefb16e90f4cbb9de4a5b6b7f6c6a3831cefa0f20cccb9e7c7b01c20", Y: "3376c6734da57ab3a67c7792eeea20707d16992dd2c827a59499f4c056b00d08", }, finalKeyData: { - evmAddress: "0x327b2742768B436d09153429E762FADB54413Ded", + walletAddress: "0x327b2742768B436d09153429E762FADB54413Ded", X: "1567e030ca76e520c180c50bc6baed07554ebc35c3132495451173e9310d8be5", Y: "123c0560757ffe6498bf2344165d0f295ea74eb8884683675e5f17ae7bb41cdb", }, @@ -61,21 +61,25 @@ describe("torus utils sapphire mainnet", function () { }); }); - it.skip("should be able to import a key for a new user", async function () { + it("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(); + const ec = new EC("secp256k1"); + + const privKeyBuffer = generatePrivateKey(ec, Buffer); const privHex = privKeyBuffer.toString("hex"); const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: email }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.importPrivateKey( - torusNodeEndpoints, - nodeDetails.torusIndexes, - nodeDetails.torusNodePub, - TORUS_TEST_VERIFIER, - { verifier_id: email }, - token, - privHex + getImportKeyParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + nodeDetails.torusNodePub, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + privHex + ) ); expect(result.finalKeyData.privKey).to.be.equal(privHex); }); @@ -86,10 +90,10 @@ describe("torus utils sapphire mainnet", function () { const verifierDetails = { verifier, verifierId: email }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const { finalKeyData, oAuthKeyData, metadata } = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(finalKeyData.evmAddress).to.not.equal(""); - expect(finalKeyData.evmAddress).to.not.equal(null); - expect(oAuthKeyData.evmAddress).to.not.equal(""); - expect(oAuthKeyData.evmAddress).to.not.equal(null); + expect(finalKeyData.walletAddress).to.not.equal(""); + expect(finalKeyData.walletAddress).to.not.equal(null); + expect(oAuthKeyData.walletAddress).to.not.equal(""); + expect(oAuthKeyData.walletAddress).to.not.equal(null); expect(metadata.typeOfUser).to.equal("v2"); expect(metadata.upgraded).to.equal(false); }); @@ -103,8 +107,8 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.eql(new BN("0")); expect(result.metadata.upgraded).to.equal(false); @@ -119,18 +123,18 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.be.equal("0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A"); + expect(result.finalKeyData.walletAddress).to.be.equal("0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A", + walletAddress: "0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A", X: "a772c71ca6c650506f26a180456a6bdf462996781a10f1740f4e65314f360f29", Y: "776c2178ff4620c67197b2f26b1222503919ff26a7cbd0fdbc91a2c9764e56cb", }, finalKeyData: { - evmAddress: "0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A", + walletAddress: "0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A", X: "a772c71ca6c650506f26a180456a6bdf462996781a10f1740f4e65314f360f29", Y: "776c2178ff4620c67197b2f26b1222503919ff26a7cbd0fdbc91a2c9764e56cb", }, @@ -153,14 +157,17 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifierId: email, verifier: TORUS_TEST_VERIFIER }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { extended_verifier_id: tssVerifierId, verifier_id: email }, - token + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { extended_verifier_id: tssVerifierId, verifier_id: email }, + token, + nodeDetails.torusNodePub + ) ); expect(result.finalKeyData.privKey).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.eql(new BN("0")); expect(result.metadata.upgraded).to.equal(true); @@ -171,18 +178,18 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB"); + expect(result.finalKeyData.walletAddress).to.equal("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC", + walletAddress: "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC", X: "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8", Y: "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c", }, finalKeyData: { - evmAddress: "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", + walletAddress: "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", X: "b943bfdc29c515195270d3a219da6a57bcaf6e58e57d03e2accb8c716e6949c8", Y: "a0fe9ac87310d302a821f89a747d80c9b7dc5cbd0956571f84b09e58d11eee90", }, @@ -204,17 +211,17 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB"); + expect(result.finalKeyData.walletAddress).to.equal("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB"); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC", + walletAddress: "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC", X: "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8", Y: "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c", }, finalKeyData: { - evmAddress: "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", + walletAddress: "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", X: "b943bfdc29c515195270d3a219da6a57bcaf6e58e57d03e2accb8c716e6949c8", Y: "a0fe9ac87310d302a821f89a747d80c9b7dc5cbd0956571f84b09e58d11eee90", }, @@ -238,11 +245,14 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - HashEnabledVerifier, - { verifier_id: TORUS_TEST_EMAIL }, - token + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + HashEnabledVerifier, + { verifier_id: TORUS_TEST_EMAIL }, + token, + nodeDetails.torusNodePub + ) ); expect(result.finalKeyData.privKey).to.be.equal("13941ecd812b08d8a33a20bc975f0cd1c3f82de25b20c0c863ba5f21580b65f6"); expect(result.metadata.serverTimeOffset).lessThan(20); @@ -250,13 +260,18 @@ describe("torus utils sapphire mainnet", function () { expect(result).eql({ finalKeyData: { - evmAddress: "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", + walletAddress: "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", X: "b943bfdc29c515195270d3a219da6a57bcaf6e58e57d03e2accb8c716e6949c8", Y: "a0fe9ac87310d302a821f89a747d80c9b7dc5cbd0956571f84b09e58d11eee90", privKey: "13941ecd812b08d8a33a20bc975f0cd1c3f82de25b20c0c863ba5f21580b65f6", }, oAuthKeyData: { - evmAddress: "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC", + walletAddress: "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC", + X: "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8", + Y: "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c", + privKey: "d768b327cbde681e5850a7d14f1c724bba2b8f8ab7fe2b1c4f1ee6979fc25478", + }, + postboxKeyData: { X: "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8", Y: "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c", privKey: "d768b327cbde681e5850a7d14f1c724bba2b8f8ab7fe2b1c4f1ee6979fc25478", @@ -281,8 +296,10 @@ describe("torus utils sapphire mainnet", function () { it("should be able to login", async function () { const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const result = await torus.retrieveShares(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const result = await torus.retrieveShares( + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, torusNodePub) + ); expect(result.finalKeyData.privKey).to.be.equal("dfb39b84e0c64b8c44605151bf8670ae6eda232056265434729b6a8a50fa3419"); expect(result.metadata.serverTimeOffset).lessThan(20); @@ -290,13 +307,18 @@ describe("torus utils sapphire mainnet", function () { expect(result).eql({ finalKeyData: { - evmAddress: "0x70520A7F04868ACad901683699Fa32765C9F6871", + walletAddress: "0x70520A7F04868ACad901683699Fa32765C9F6871", X: "adff099b5d3b1e238b43fba1643cfa486e8d9e8de22c1e6731d06a5303f9025b", Y: "21060328e7889afd303acb63201b6493e3061057d1d81279931ab4a6cabf94d4", privKey: "dfb39b84e0c64b8c44605151bf8670ae6eda232056265434729b6a8a50fa3419", }, oAuthKeyData: { - evmAddress: "0x925c97404F1aBdf4A8085B93edC7B9F0CEB3C673", + walletAddress: "0x925c97404F1aBdf4A8085B93edC7B9F0CEB3C673", + X: "5cd8625fc01c7f7863a58c914a8c43b2833b3d0d5059350bab4acf6f4766a33d", + Y: "198a4989615c5c2c7fa4d49c076ea7765743d09816bb998acb9ff54f5db4a391", + privKey: "90a219ac78273e82e36eaa57c15f9070195e436644319d6b9aea422bb4d31906", + }, + postboxKeyData: { X: "5cd8625fc01c7f7863a58c914a8c43b2833b3d0d5059350bab4acf6f4766a33d", Y: "198a4989615c5c2c7fa4d49c076ea7765743d09816bb998acb9ff54f5db4a391", privKey: "90a219ac78273e82e36eaa57c15f9070195e436644319d6b9aea422bb4d31906", @@ -324,19 +346,22 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: email, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: email, - }, - hashedIdToken.substring(2) + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: email, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: email, + }, + hashedIdToken.substring(2), + nodeDetails.torusNodePub + ) ); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.finalKeyData.evmAddress).to.not.equal(""); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(""); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.not.equal(null); expect(result.metadata.upgraded).to.equal(false); @@ -354,11 +379,14 @@ describe("torus utils sapphire mainnet", function () { TorusUtils.setSessionTime(customSessionTime); // 1hr const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: TORUS_TEST_EMAIL }, + token, + nodeDetails.torusNodePub + ) ); const signatures = result.sessionData.sessionTokenData.map((s) => ({ data: s.token, sig: s.signature })); diff --git a/test/testnet.test.ts b/test/testnet.test.ts index b8637a7..e495699 100644 --- a/test/testnet.test.ts +++ b/test/testnet.test.ts @@ -8,7 +8,7 @@ import { useFakeTimers } from "sinon"; import { keccak256, TorusPublicKey } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken } from "./helpers"; +import { generateIdToken, getRetrieveSharesParams } from "./helpers"; const TORUS_TEST_EMAIL = "archit1@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; @@ -30,18 +30,18 @@ describe("torus utils migrated testnet on sapphire", function () { 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("0x9bcBAde70546c0796c00323CD1b97fa0a425A506"); + expect(result.finalKeyData.walletAddress).to.equal("0x9bcBAde70546c0796c00323CD1b97fa0a425A506"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0x9bcBAde70546c0796c00323CD1b97fa0a425A506", + walletAddress: "0x9bcBAde70546c0796c00323CD1b97fa0a425A506", X: "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5", Y: "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438", }, finalKeyData: { - evmAddress: "0x9bcBAde70546c0796c00323CD1b97fa0a425A506", + walletAddress: "0x9bcBAde70546c0796c00323CD1b97fa0a425A506", X: "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5", Y: "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438", }, @@ -58,9 +58,9 @@ describe("torus utils migrated testnet on sapphire", function () { it("should fetch user type and public address", async function () { const verifier = "google-lrc"; // any verifier 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("0xf5804f608C233b9cdA5952E46EB86C9037fd6842"); + const { torusNodeEndpoints } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const result1 = await torus.getUserTypeAndAddress(torusNodeEndpoints, verifierDetails); + expect(result1.finalKeyData.walletAddress).to.equal("0xf5804f608C233b9cdA5952E46EB86C9037fd6842"); expect(result1.metadata.typeOfUser).to.equal("v2"); expect(result1.metadata.serverTimeOffset).lessThan(20); @@ -68,12 +68,12 @@ describe("torus utils migrated testnet on sapphire", function () { expect(result1).eql({ oAuthKeyData: { - evmAddress: "0x9bcBAde70546c0796c00323CD1b97fa0a425A506", + walletAddress: "0x9bcBAde70546c0796c00323CD1b97fa0a425A506", X: "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5", Y: "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438", }, finalKeyData: { - evmAddress: "0xf5804f608C233b9cdA5952E46EB86C9037fd6842", + walletAddress: "0xf5804f608C233b9cdA5952E46EB86C9037fd6842", X: "ed737569a557b50722a8b5c0e4e5ca30cef1ede2f5674a0616b78246bb93dfd0", Y: "d9e8e6c54c12c4da38c2f0d1047fcf6089036127738f4ef72a83431339586ca9", }, @@ -92,11 +92,11 @@ describe("torus utils migrated testnet on sapphire", function () { const v2Verifier = "tkey-google-lrc"; // 1/1 user const v2TestEmail = "somev2user@gmail.com"; - const result2 = (await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, { + const result2 = (await torus.getUserTypeAndAddress(torusNodeEndpoints, { verifier: v2Verifier, verifierId: v2TestEmail, })) as TorusPublicKey; - expect(result2.finalKeyData.evmAddress).to.equal("0xE91200d82029603d73d6E307DbCbd9A7D0129d8D"); + expect(result2.finalKeyData.walletAddress).to.equal("0xE91200d82029603d73d6E307DbCbd9A7D0129d8D"); expect(result2.metadata.typeOfUser).to.equal("v2"); expect(result2.metadata.serverTimeOffset).lessThan(20); @@ -104,12 +104,12 @@ describe("torus utils migrated testnet on sapphire", function () { expect(result2).eql({ oAuthKeyData: { - evmAddress: "0x376597141d8d219553378313d18590F373B09795", + walletAddress: "0x376597141d8d219553378313d18590F373B09795", X: "86cd2db15b7a9937fa8ab7d0bf8e7f4113b64d1f4b2397aad35d6d4749d2fb6c", Y: "86ef47a3724144331c31a3a322d85b6fc1a5d113b41eaa0052053b6e3c74a3e2", }, finalKeyData: { - evmAddress: "0xE91200d82029603d73d6E307DbCbd9A7D0129d8D", + walletAddress: "0xE91200d82029603d73d6E307DbCbd9A7D0129d8D", X: "c350e338dde24df986915992fea6e0aef3560c245ca144ee7fe1498784c4ef4e", Y: "a605e52b65d3635f89654519dfa7e31f7b45f206ef4189866ad0c2240d40f97f", }, @@ -127,22 +127,22 @@ describe("torus utils migrated testnet on sapphire", function () { // 2/n user const v2nTestEmail = "caspertorus@gmail.com"; - const result3 = (await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, { + const result3 = (await torus.getUserTypeAndAddress(torusNodeEndpoints, { verifier: v2Verifier, verifierId: v2nTestEmail, })) as TorusPublicKey; - expect(result3.finalKeyData.evmAddress).to.equal("0x1016DA7c47A04C76036637Ea02AcF1d29c64a456"); + expect(result3.finalKeyData.walletAddress).to.equal("0x1016DA7c47A04C76036637Ea02AcF1d29c64a456"); expect(result3.metadata.typeOfUser).to.equal("v2"); delete result3.metadata.serverTimeOffset; expect(result3).eql({ oAuthKeyData: { - evmAddress: "0xd45383fbF04BccFa0450d7d8ee453ca86b7C6544", + walletAddress: "0xd45383fbF04BccFa0450d7d8ee453ca86b7C6544", X: "d25cc473fbb448d20b5551f3c9aa121e1924b3d197353347187c47ad13ecd5d8", Y: "3394000f43160a925e6c3017dde1354ecb2b61739571c6584f58edd6b923b0f5", }, finalKeyData: { - evmAddress: "0x1016DA7c47A04C76036637Ea02AcF1d29c64a456", + walletAddress: "0x1016DA7c47A04C76036637Ea02AcF1d29c64a456", X: "d3e222f6b23f0436b7c86e9cc4164eb5ea8448e4c0e7539c8b4f7fd00e8ec5c7", Y: "1c47f5faccec6cf57c36919f6f0941fe3d8d65033cf2cc78f209304386044222", }, @@ -165,10 +165,10 @@ describe("torus utils migrated testnet on sapphire", function () { const verifierDetails = { verifier, verifierId: email }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const { finalKeyData, oAuthKeyData, metadata } = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(finalKeyData.evmAddress).to.not.equal(""); - expect(finalKeyData.evmAddress).to.not.equal(null); - expect(oAuthKeyData.evmAddress).to.not.equal(""); - expect(oAuthKeyData.evmAddress).to.not.equal(null); + expect(finalKeyData.walletAddress).to.not.equal(""); + expect(finalKeyData.walletAddress).to.not.equal(null); + expect(oAuthKeyData.walletAddress).to.not.equal(""); + expect(oAuthKeyData.walletAddress).to.not.equal(null); expect(metadata.typeOfUser).to.equal("v1"); expect(metadata.upgraded).to.equal(false); }); @@ -176,21 +176,28 @@ describe("torus utils migrated testnet on sapphire", function () { it("should be able to login", async function () { const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const result = await torus.retrieveShares(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const result = await torus.retrieveShares( + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, torusNodePub) + ); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result.finalKeyData.privKey).to.be.equal("9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3"); expect(result).eql({ finalKeyData: { - evmAddress: "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6", + walletAddress: "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6", X: "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd", Y: "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9", privKey: "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3", }, oAuthKeyData: { - evmAddress: "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6", + walletAddress: "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6", + X: "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd", + Y: "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9", + privKey: "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3", + }, + postboxKeyData: { X: "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd", Y: "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9", privKey: "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3", @@ -208,33 +215,41 @@ describe("torus utils migrated testnet on sapphire", function () { const idToken = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const hashedIdToken = keccak256(Buffer.from(idToken, "utf8")); const verifierDetails = { verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: TORUS_TEST_EMAIL }; - const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: TORUS_TEST_EMAIL, - }, - hashedIdToken.substring(2) + getRetrieveSharesParams( + torusNodeEndpoints, + torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: TORUS_TEST_EMAIL, + }, + hashedIdToken.substring(2), + torusNodePub + ) ); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result.metadata.typeOfUser).to.be.equal("v1"); - expect(result.oAuthKeyData.evmAddress).to.be.equal("0x938a40E155d118BD31E439A9d92D67bd55317965"); - expect(result.finalKeyData.evmAddress).to.be.equal("0x938a40E155d118BD31E439A9d92D67bd55317965"); + expect(result.oAuthKeyData.walletAddress).to.be.equal("0x938a40E155d118BD31E439A9d92D67bd55317965"); + expect(result.finalKeyData.walletAddress).to.be.equal("0x938a40E155d118BD31E439A9d92D67bd55317965"); expect(result).eql({ finalKeyData: { - evmAddress: "0x938a40E155d118BD31E439A9d92D67bd55317965", + walletAddress: "0x938a40E155d118BD31E439A9d92D67bd55317965", X: "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95", Y: "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6", privKey: "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1", }, oAuthKeyData: { - evmAddress: "0x938a40E155d118BD31E439A9d92D67bd55317965", + walletAddress: "0x938a40E155d118BD31E439A9d92D67bd55317965", + X: "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95", + Y: "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6", + privKey: "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1", + }, + postboxKeyData: { X: "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95", Y: "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6", privKey: "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1", @@ -260,9 +275,11 @@ describe("torus utils migrated testnet on sapphire", function () { enableOneKey: true, serverTimeOffset: -700, }); - const { torusNodeSSSEndpoints: torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const { torusNodeSSSEndpoints: torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); try { - await legacyTorus.retrieveShares(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: email }, token); + await legacyTorus.retrieveShares( + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: email }, token, torusNodePub) + ); fail("should not reach here"); } catch (err) { expect((err as { status: number }).status).to.equal(403);