diff --git a/mpc-core-kit/tkey-mpc-react-bitcoin-example/package-lock.json b/mpc-core-kit/tkey-mpc-react-bitcoin-example/package-lock.json index 77def0f5..b9e6f454 100644 --- a/mpc-core-kit/tkey-mpc-react-bitcoin-example/package-lock.json +++ b/mpc-core-kit/tkey-mpc-react-bitcoin-example/package-lock.json @@ -20,6 +20,7 @@ "@tkey-mpc/share-serialization": "^8.1.0", "@tkey-mpc/storage-layer-torus": "^8.1.0", "@toruslabs/constants": "^10.0.0", + "@toruslabs/customauth": "^16.0.1", "@toruslabs/eslint-config-typescript": "^2.0.0", "@toruslabs/fnd-base": "^12.0.0", "@toruslabs/openlogin-session-manager": "^2.0.0", @@ -1790,16 +1791,21 @@ "license": "MIT" }, "node_modules/@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.10.tgz", + "integrity": "sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, "node_modules/@babel/template": { "version": "7.20.7", "license": "MIT", @@ -3453,7 +3459,8 @@ }, "node_modules/@socket.io/component-emitter": { "version": "3.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" }, "node_modules/@surma/rollup-plugin-off-main-thread": { "version": "2.2.3", @@ -4202,6 +4209,203 @@ "@babel/runtime": "7.x" } }, + "node_modules/@toruslabs/customauth": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@toruslabs/customauth/-/customauth-16.0.1.tgz", + "integrity": "sha512-H3Pqc16j55FxYB5xBYUJNE8wO2RnSOw4gGVkWFhfGuVcaSNlpBMwxwg+B7Yy95TdaEce8q1bNdIgXrrd4KKeKA==", + "dependencies": { + "@chaitanyapotti/register-service-worker": "^1.7.3", + "@toruslabs/broadcast-channel": "^8.0.0", + "@toruslabs/constants": "^13.0.1", + "@toruslabs/eccrypto": "^4.0.0", + "@toruslabs/fetch-node-details": "^13.0.1", + "@toruslabs/http-helpers": "^5.0.0", + "@toruslabs/metadata-helpers": "^5.0.0", + "@toruslabs/torus.js": "^11.0.2", + "bowser": "^2.11.0", + "events": "^3.3.0", + "jwt-decode": "^3.1.2", + "lodash.merge": "^4.6.2", + "loglevel": "^1.8.1" + }, + "engines": { + "node": ">=18.x", + "npm": ">=9.x" + }, + "peerDependencies": { + "@babel/runtime": "^7.x", + "@sentry/types": "^7.x" + }, + "peerDependenciesMeta": { + "@sentry/types": { + "optional": true + } + } + }, + "node_modules/@toruslabs/customauth/node_modules/@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@toruslabs/customauth/node_modules/@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@toruslabs/customauth/node_modules/@scure/bip32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", + "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", + "dependencies": { + "@noble/curves": "~1.1.0", + "@noble/hashes": "~1.3.1", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@toruslabs/customauth/node_modules/@scure/bip39": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", + "dependencies": { + "@noble/hashes": "~1.3.0", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@toruslabs/customauth/node_modules/@toruslabs/broadcast-channel": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@toruslabs/broadcast-channel/-/broadcast-channel-8.0.0.tgz", + "integrity": "sha512-qCyWsHVL4Xtx1J6k1+acD7TJKCelJWyUy5Q5zyiWMPxMGFxTv1XdRyqpzV+VgwbcslIqgFN0GewOry2l1jlUQQ==", + "dependencies": { + "@babel/runtime": "^7.22.10", + "@toruslabs/eccrypto": "^4.0.0", + "@toruslabs/metadata-helpers": "^5.0.0", + "bowser": "^2.11.0", + "loglevel": "^1.8.1", + "oblivious-set": "1.1.1", + "socket.io-client": "^4.7.2", + "unload": "^2.4.1" + }, + "engines": { + "node": ">=18.x", + "npm": ">=9.x" + } + }, + "node_modules/@toruslabs/customauth/node_modules/@toruslabs/constants": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/@toruslabs/constants/-/constants-13.0.1.tgz", + "integrity": "sha512-haFppvgyHfKl2uTQKkrWOkgQmLgzbqxhIvaNvRGei4FgFNJNLr5+ju8/PwwbgKhQUi7adkeU0pjwFYITJyHEPw==", + "engines": { + "node": ">=18.x", + "npm": ">=9.x" + }, + "peerDependencies": { + "@babel/runtime": "7.x" + } + }, + "node_modules/@toruslabs/customauth/node_modules/@toruslabs/eccrypto": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@toruslabs/eccrypto/-/eccrypto-4.0.0.tgz", + "integrity": "sha512-Z3EINkbsgJx1t6jCDVIJjLSUEGUtNIeDjhMWmeDGOWcP/+v/yQ1hEvd1wfxEz4q5WqIHhevacmPiVxiJ4DljGQ==", + "dependencies": { + "elliptic": "^6.5.4" + }, + "engines": { + "node": ">=18.x", + "npm": ">=9.x" + } + }, + "node_modules/@toruslabs/customauth/node_modules/@toruslabs/http-helpers": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@toruslabs/http-helpers/-/http-helpers-5.0.0.tgz", + "integrity": "sha512-GmezWz9JeF6YyhjLSm+9XDF4YaeICEckY0Jbo43i86SjhfJYgRWqEi63VSiNsaqc/z810Q0FQvEk1TnBRX2tgA==", + "dependencies": { + "lodash.merge": "^4.6.2", + "loglevel": "^1.8.1" + }, + "engines": { + "node": ">=18.x", + "npm": ">=9.x" + }, + "peerDependencies": { + "@babel/runtime": "^7.x", + "@sentry/types": "^7.x" + }, + "peerDependenciesMeta": { + "@sentry/types": { + "optional": true + } + } + }, + "node_modules/@toruslabs/customauth/node_modules/@toruslabs/metadata-helpers": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@toruslabs/metadata-helpers/-/metadata-helpers-5.0.0.tgz", + "integrity": "sha512-ZUFfOHJVJC53c8wJYHjdF3bIgN2ZvfqehbTZ/zJ7oVFfrrd6O66V3gQ1i1zxBjH3yhOvZKQwc0DaMmh3G0NUXQ==", + "dependencies": { + "@toruslabs/eccrypto": "^4.0.0", + "@toruslabs/http-helpers": "^5.0.0", + "elliptic": "^6.5.4", + "ethereum-cryptography": "^2.1.2", + "json-stable-stringify": "^1.0.2" + }, + "engines": { + "node": ">=18.x", + "npm": ">=9.x" + }, + "peerDependencies": { + "@babel/runtime": "7.x" + } + }, + "node_modules/@toruslabs/customauth/node_modules/@toruslabs/torus.js": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@toruslabs/torus.js/-/torus.js-11.0.2.tgz", + "integrity": "sha512-AWa0+PhzoYH/nONnBp3UzR9HwhB0kqbFBaRnNpBmpLB1ewbKwbP/AEyFkJK+dcEfRosCPaqLjnef0nLCJ/hq5w==", + "dependencies": { + "@toruslabs/constants": "^13.0.1", + "@toruslabs/eccrypto": "^4.0.0", + "@toruslabs/http-helpers": "^5.0.0", + "bn.js": "^5.2.1", + "elliptic": "^6.5.4", + "ethereum-cryptography": "^2.1.2", + "json-stable-stringify": "^1.0.2", + "loglevel": "^1.8.1" + }, + "engines": { + "node": ">=18.x", + "npm": ">=9.x" + }, + "peerDependencies": { + "@babel/runtime": "7.x" + } + }, + "node_modules/@toruslabs/customauth/node_modules/ethereum-cryptography": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", + "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", + "dependencies": { + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + } + }, "node_modules/@toruslabs/eccrypto": { "version": "1.1.8", "hasInstallScript": true, @@ -4272,6 +4476,73 @@ "typescript": "^4.x" } }, + "node_modules/@toruslabs/fetch-node-details": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/@toruslabs/fetch-node-details/-/fetch-node-details-13.0.1.tgz", + "integrity": "sha512-05WfFlrkIibO5VdYdx5+B70owzasXzRMSm19KYF/Iw/ch3jbRIC10tKtQMs2wGfpcMX+ngmGtlRYndUcy1UikA==", + "dependencies": { + "@toruslabs/constants": "^13.0.1", + "@toruslabs/fnd-base": "^13.0.1", + "@toruslabs/http-helpers": "^5.0.0", + "loglevel": "^1.8.1" + }, + "engines": { + "node": ">=18.x", + "npm": ">=9.x" + }, + "peerDependencies": { + "@babel/runtime": "7.x" + } + }, + "node_modules/@toruslabs/fetch-node-details/node_modules/@toruslabs/constants": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/@toruslabs/constants/-/constants-13.0.1.tgz", + "integrity": "sha512-haFppvgyHfKl2uTQKkrWOkgQmLgzbqxhIvaNvRGei4FgFNJNLr5+ju8/PwwbgKhQUi7adkeU0pjwFYITJyHEPw==", + "engines": { + "node": ">=18.x", + "npm": ">=9.x" + }, + "peerDependencies": { + "@babel/runtime": "7.x" + } + }, + "node_modules/@toruslabs/fetch-node-details/node_modules/@toruslabs/fnd-base": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/@toruslabs/fnd-base/-/fnd-base-13.0.1.tgz", + "integrity": "sha512-HJE+NAFBWIZmk9DN38n71epbdqulIc2lJDb2UU+RMqYh4YArjab4JRbBew2rye0SDyhCXSIAw4GHjEH9UYi9Zg==", + "dependencies": { + "@toruslabs/constants": "^13.0.1" + }, + "engines": { + "node": ">=18.x", + "npm": ">=9.x" + }, + "peerDependencies": { + "@babel/runtime": "7.x" + } + }, + "node_modules/@toruslabs/fetch-node-details/node_modules/@toruslabs/http-helpers": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@toruslabs/http-helpers/-/http-helpers-5.0.0.tgz", + "integrity": "sha512-GmezWz9JeF6YyhjLSm+9XDF4YaeICEckY0Jbo43i86SjhfJYgRWqEi63VSiNsaqc/z810Q0FQvEk1TnBRX2tgA==", + "dependencies": { + "lodash.merge": "^4.6.2", + "loglevel": "^1.8.1" + }, + "engines": { + "node": ">=18.x", + "npm": ">=9.x" + }, + "peerDependencies": { + "@babel/runtime": "^7.x", + "@sentry/types": "^7.x" + }, + "peerDependenciesMeta": { + "@sentry/types": { + "optional": true + } + } + }, "node_modules/@toruslabs/fnd-base": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@toruslabs/fnd-base/-/fnd-base-12.0.0.tgz", @@ -8679,19 +8950,21 @@ } }, "node_modules/engine.io-client": { - "version": "6.4.0", - "license": "MIT", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.2.tgz", + "integrity": "sha512-CQZqbrpEYnrpGqC07a9dJDz4gePZUgTPMU3NKJPSeQOyw27Tst4Pl3FemKoFGAlHzgZmKjoRmiJvbWfhCXUlIg==", "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", + "engine.io-parser": "~5.2.1", "ws": "~8.11.0", "xmlhttprequest-ssl": "~2.0.0" } }, "node_modules/engine.io-client/node_modules/ws": { "version": "8.11.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "engines": { "node": ">=10.0.0" }, @@ -8709,8 +8982,9 @@ } }, "node_modules/engine.io-parser": { - "version": "5.0.6", - "license": "MIT", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", + "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==", "engines": { "node": ">=10.0.0" } @@ -16638,22 +16912,23 @@ } }, "node_modules/socket.io-client": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.6.1.tgz", - "integrity": "sha512-5UswCV6hpaRsNg5kkEHVcbBIXEYoVbMQaHJBXJCyEQ+CiFPV1NIOY0XOFWG4XR4GZcB8Kn6AsRs/9cy9TbqVMQ==", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz", + "integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==", "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.2", - "engine.io-client": "~6.4.0", - "socket.io-parser": "~4.2.1" + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" }, "engines": { "node": ">=10.0.0" } }, "node_modules/socket.io-parser": { - "version": "4.2.2", - "license": "MIT", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" @@ -19224,6 +19499,8 @@ }, "node_modules/xmlhttprequest-ssl": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", "engines": { "node": ">=0.4.0" } diff --git a/mpc-core-kit/tkey-mpc-react-bitcoin-example/package.json b/mpc-core-kit/tkey-mpc-react-bitcoin-example/package.json index b9c0c00d..2a37c907 100644 --- a/mpc-core-kit/tkey-mpc-react-bitcoin-example/package.json +++ b/mpc-core-kit/tkey-mpc-react-bitcoin-example/package.json @@ -15,6 +15,7 @@ "@tkey-mpc/share-serialization": "^8.1.0", "@tkey-mpc/storage-layer-torus": "^8.1.0", "@toruslabs/constants": "^10.0.0", + "@toruslabs/customauth": "^16.0.1", "@toruslabs/eslint-config-typescript": "^2.0.0", "@toruslabs/fnd-base": "^12.0.0", "@toruslabs/openlogin-session-manager": "^2.0.0", diff --git a/mpc-core-kit/tkey-mpc-react-bitcoin-example/src/App.tsx b/mpc-core-kit/tkey-mpc-react-bitcoin-example/src/App.tsx index 5978ec0a..ebc4694e 100644 --- a/mpc-core-kit/tkey-mpc-react-bitcoin-example/src/App.tsx +++ b/mpc-core-kit/tkey-mpc-react-bitcoin-example/src/App.tsx @@ -15,6 +15,10 @@ import ecc from "@bitcoinerlab/secp256k1"; import ECPairFactory from "ecpair"; import { testnet } from "bitcoinjs-lib/src/networks"; import { p2pkh } from "bitcoinjs-lib/src/payments"; +import { TorusServiceProvider } from "@tkey-mpc/service-provider-torus"; +import { ShareSerializationModule } from "@tkey-mpc/share-serialization"; +import {TorusLoginResponse} from "@toruslabs/customauth"; +import { SignerAsync } from "bitcoinjs-lib"; const { getTSSPubKey } = utils; const ECPair = ECPairFactory(ecc); @@ -31,12 +35,12 @@ const BTCValidator = (pubkey: Buffer, msghash: Buffer, signature: Buffer): boole function App() { - const [loginResponse, setLoginResponse] = useState(null); + const [loginResponse, setLoginResponse] = useState(null); const [user, setUser] = useState(null); - const [metadataKey, setMetadataKey] = useState(); + const [metadataKey, setMetadataKey] = useState(); const [localFactorKey, setLocalFactorKey] = useState(null); - const [oAuthShare, setOAuthShare] = useState(null); - const [web3, setWeb3] = useState(null); + const [oAuthShare, setOAuthShare] = useState(null); + const [web3, setWeb3] = useState(null); const [signingParams, setSigningParams] = useState(null); const [bitcoinUTXID, setBitcoinUTXID] = useState(null); const [fundingTxIndex, setFundingTxIndex] = useState(null); @@ -47,13 +51,14 @@ function App() { useEffect(() => { if (!localFactorKey) return; localStorage.setItem( - `tKeyLocalStore\u001c${loginResponse.userInfo.verifier}\u001c${loginResponse.userInfo.verifierId}`, + `tKeyLocalStore\u001c${loginResponse!.userInfo.verifier}\u001c${loginResponse!.userInfo.verifierId}`, JSON.stringify({ factorKey: localFactorKey.toString("hex"), - verifier: loginResponse.userInfo.verifier, - verifierId: loginResponse.userInfo.verifierId, + verifier: loginResponse!.userInfo.verifier, + verifierId: loginResponse!.userInfo.verifierId, }) ); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [localFactorKey]); useEffect(() => { @@ -83,8 +88,8 @@ function App() { const metadataDeviceShare = metadataShare.deviceShare; tKey.serviceProvider.postboxKey = new BN(signingParams.oAuthShare, "hex"); - (tKey.serviceProvider as any).verifierName = signingParams.userInfo.verifier; - (tKey.serviceProvider as any).verifierId = signingParams.userInfo.verifierId; + (tKey.serviceProvider as TorusServiceProvider).verifierName = signingParams.userInfo.verifier; + (tKey.serviceProvider as TorusServiceProvider).verifierId = signingParams.userInfo.verifierId; await tKey.initialize({ neverInitializeNewKey: true }); await tKey.inputShareStoreSafe(metadataDeviceShare, true); @@ -137,7 +142,7 @@ function App() { } try { // Triggering Login using Service Provider ==> opens the popup - const loginResponse = await (tKey.serviceProvider as any).triggerLogin({ + const loginResponse: TorusLoginResponse = await (tKey.serviceProvider as TorusServiceProvider).triggerLogin({ typeOfLogin: "google", verifier: "google-tkey-w3a", clientId: "774338308167-q463s7kpvja16l4l0kko3nb925ikds2p.apps.googleusercontent.com", @@ -163,13 +168,13 @@ function App() { try { const loginResponse = await triggerLogin(); // Calls the triggerLogin() function above - const OAuthShare = new BN(TorusUtils.getPostboxKey(loginResponse), "hex"); + const OAuthShare = new BN(TorusUtils.getPostboxKey(loginResponse!), "hex"); setOAuthShare(OAuthShare); //@ts-ignore const signatures = loginResponse.sessionData.sessionTokenData.filter(i => Boolean(i)).map((session) => JSON.stringify({ data: session.token, sig: session.signature })); const tKeyLocalStoreString = localStorage.getItem( - `tKeyLocalStore\u001c${loginResponse.userInfo.verifier}\u001c${loginResponse.userInfo.verifierId}` + `tKeyLocalStore\u001c${loginResponse!.userInfo.verifier}\u001c${loginResponse!.userInfo.verifierId}` ); const tKeyLocalStore = JSON.parse(tKeyLocalStoreString || "{}"); @@ -189,7 +194,7 @@ function App() { deviceTSSIndex, }); } else { - if (tKeyLocalStore.verifier === loginResponse.userInfo.verifier && tKeyLocalStore.verifierId === loginResponse.userInfo.verifierId) { + if (tKeyLocalStore.verifier === loginResponse!.userInfo.verifier && tKeyLocalStore.verifierId === loginResponse!.userInfo.verifierId) { factorKey = new BN(tKeyLocalStore.factorKey, "hex"); } else { try { @@ -197,7 +202,7 @@ function App() { content: "input" as any, }).then(async (value) => { uiConsole(value); - return await (tKey.modules.shareSerialization as any).deserialize(value, "mnemonic"); + return await (tKey.modules.shareSerialization as ShareSerializationModule).deserialize(value, "mnemonic"); }); } catch (error) { uiConsole(error); @@ -264,7 +269,7 @@ function App() { // 5. save factor key and other metadata if ( !existingUser || - !(tKeyLocalStore.verifier === loginResponse.userInfo.verifier && tKeyLocalStore.verifierId === loginResponse.userInfo.verifierId) + !(tKeyLocalStore.verifier === loginResponse!.userInfo.verifier && tKeyLocalStore.verifierId === loginResponse!.userInfo.verifierId) ) { await addFactorKeyMetadata(tKey, factorKey, tssShare2, tssShare2Index, "local storage share"); } @@ -275,7 +280,7 @@ function App() { const nodeDetails = await tKey.serviceProvider.getTSSNodeDetails() const signingParams = { - oAuthShare: loginResponse.privateKey, + oAuthShare: OAuthShare, factorKey, btcAddress, ecPublicKey: ECPubKey.publicKey, @@ -284,7 +289,7 @@ function App() { tssShare2Index, compressedTSSPubKey, signatures, - userInfo: loginResponse.userInfo, + userInfo: loginResponse!.userInfo, nodeDetails, }; @@ -353,7 +358,7 @@ function App() { const { tssShare: tssShare2, tssIndex: tssIndex2 } = await tKey.getTSSShare(localFactorKey); await addFactorKeyMetadata(tKey, backupFactorKey, tssShare2, tssIndex2, "manual share"); - const serializedShare = await (tKey.modules.shareSerialization as any).serialize(backupFactorKey, "mnemonic"); + const serializedShare = await (tKey.modules.shareSerialization as ShareSerializationModule).serialize(backupFactorKey, "mnemonic"); await tKey.syncLocalMetadataTransitions(); uiConsole("Successfully created manual backup. Manual Backup Factor: ", serializedShare); } catch (err) { @@ -389,7 +394,7 @@ function App() { const { tssShare: tssShare2, tssIndex: tssIndex2 } = await tKey.getTSSShare(backupFactorKey); await addFactorKeyMetadata(tKey, backupFactorKey, tssShare2, tssIndex2, "manual share"); - const serializedShare = await (tKey.modules.shareSerialization as any).serialize(backupFactorKey, "mnemonic"); + const serializedShare = await (tKey.modules.shareSerialization as ShareSerializationModule).serialize(backupFactorKey, "mnemonic"); await tKey.syncLocalMetadataTransitions(); uiConsole(" Successfully created manual backup.Manual Backup Factor: ", serializedShare); @@ -429,16 +434,16 @@ function App() { return loginResponse; }; - const getMetadataKey = (): void => { + const getMetadataKey = (): string => { uiConsole(metadataKey); - return metadataKey; + return metadataKey!; }; const resetAccount = async () => { try { localStorage.removeItem(`tKeyLocalStore\u001c${loginResponse.userInfo.verifier}\u001c${loginResponse.userInfo.verifierId}`); await tKey.storageLayer.setMetadata({ - privKey: oAuthShare, + privKey: oAuthShare!, input: { message: "KEY_NOT_FOUND" }, }); uiConsole("Reset Account Successful."); diff --git a/mpc-core-kit/tkey-mpc-react-bitcoin-example/src/utils.ts b/mpc-core-kit/tkey-mpc-react-bitcoin-example/src/utils.ts index e05e1dc6..dbcc8d2c 100644 --- a/mpc-core-kit/tkey-mpc-react-bitcoin-example/src/utils.ts +++ b/mpc-core-kit/tkey-mpc-react-bitcoin-example/src/utils.ts @@ -6,13 +6,12 @@ import { generatePrivate } from "@toruslabs/eccrypto"; import { Client } from "@toruslabs/tss-client"; import * as tss from "@toruslabs/tss-lib"; import keccak256 from "keccak256"; -import { TORUS_NETWORK } from "@toruslabs/constants"; import { utils } from "@toruslabs/tss-client"; import { Signer, SignerAsync } from "bitcoinjs-lib"; import { testnet } from "bitcoinjs-lib/src/networks"; +import ThresholdKey from "@tkey-mpc/core/dist/types/core"; const { getDKLSCoeff, setupSockets } = utils; -const network = TORUS_NETWORK.SAPPHIRE_DEVNET; const parties = 4; const clientIndex = parties - 1; const tssImportUrl = `https://sapphire-dev-2-2.authnetwork.dev/tss/v1/clientWasm`; @@ -166,7 +165,7 @@ export type FactorKeyCloudMetadata = { tssIndex: number; }; -const fetchDeviceShareFromTkey = async (tKey: any) => { +const fetchDeviceShareFromTkey = async (tKey: ThresholdKey) => { if (!tKey) { console.error("tKey not initialized yet"); return; @@ -188,7 +187,7 @@ const fetchDeviceShareFromTkey = async (tKey: any) => { } }; -export const addFactorKeyMetadata = async (tKey: any, factorKey: BN, tssShare: BN, tssIndex: number, factorKeyDescription: string) => { +export const addFactorKeyMetadata = async (tKey: ThresholdKey, factorKey: BN, tssShare: BN, tssIndex: number, factorKeyDescription: string) => { if (!tKey) { console.error("tKey not initialized yet"); return; @@ -222,7 +221,7 @@ export const addFactorKeyMetadata = async (tKey: any, factorKey: BN, tssShare: B await tKey.addShareDescription(factorIndex, JSON.stringify(params), true); }; -export const copyExistingTSSShareForNewFactor = async (tKey: any, newFactorPub: Point, factorKeyForExistingTSSShare: BN) => { +export const copyExistingTSSShareForNewFactor = async (tKey: ThresholdKey, newFactorPub: Point, factorKeyForExistingTSSShare: BN) => { if (!tKey) { throw new Error("tkey does not exist, cannot copy factor pub"); } @@ -260,7 +259,7 @@ export const copyExistingTSSShareForNewFactor = async (tKey: any, newFactorPub: }; export const addNewTSSShareAndFactor = async ( - tKey: any, + tKey: ThresholdKey, newFactorPub: Point, newFactorTSSIndex: number, factorKeyForExistingTSSShare: BN, diff --git a/mpc-core-kit/tkey-mpc-react-firebase-example/src/App.tsx b/mpc-core-kit/tkey-mpc-react-firebase-example/src/App.tsx index d67d8516..c902e5c1 100644 --- a/mpc-core-kit/tkey-mpc-react-firebase-example/src/App.tsx +++ b/mpc-core-kit/tkey-mpc-react-firebase-example/src/App.tsx @@ -7,7 +7,7 @@ import { generatePrivate } from "eccrypto"; import { useEffect, useState } from "react"; import swal from "sweetalert"; import { tKey, chainConfig } from "./tkey"; -import { addFactorKeyMetadata, setupWeb3, copyExistingTSSShareForNewFactor, addNewTSSShareAndFactor, getEcCrypto, gettKeyLocalStore, settKeyLocalStore } from "./utils"; +import { addFactorKeyMetadata, setupWeb3, copyExistingTSSShareForNewFactor, addNewTSSShareAndFactor, getEcCrypto, gettKeyLocalStore, settKeyLocalStore, LoginResponse, SigningParams } from "./utils"; import { utils } from "@toruslabs/tss-client"; import { initializeApp } from "firebase/app"; import { @@ -18,8 +18,9 @@ import { } from "firebase/auth"; import { TorusServiceProvider } from "@tkey-mpc/service-provider-torus"; import Web3 from "web3"; -import { ethers, id } from "ethers"; +import { ethers } from "ethers"; import { typedSignatureHash } from "@metamask/eth-sig-util"; +import { ShareSerializationModule } from "@tkey-mpc/share-serialization"; const { getTSSPubKey } = utils; @@ -42,21 +43,23 @@ const uiConsole = (...args: any[]): void => { }; + + function App() { - const [loginResponse, setLoginResponse] = useState(null); + const [loginResponse, setLoginResponse] = useState(null); const [user, setUser] = useState(null); - const [metadataKey, setMetadataKey] = useState(); + const [metadataKey, setMetadataKey] = useState(); const [localFactorKey, setLocalFactorKey] = useState(null); - const [oAuthShare, setOAuthShare] = useState(null); + const [oAuthShare, setOAuthShare] = useState(null); const [web3, setWeb3] = useState(null); - const [signingParams, setSigningParams] = useState(null); + const [signingParams, setSigningParams] = useState(null); const app = initializeApp(firebaseConfig); // Init Service Provider inside the useEffect Method useEffect(() => { if (!localFactorKey) return; - settKeyLocalStore(loginResponse, localFactorKey); + settKeyLocalStore(loginResponse!, localFactorKey); // eslint-disable-next-line react-hooks/exhaustive-deps }, [localFactorKey]); @@ -78,7 +81,7 @@ function App() { useEffect(() => { const localSetup = async () => { - const web3Local = await setupWeb3(chainConfig, loginResponse, signingParams); + const web3Local = await setupWeb3(chainConfig, loginResponse!, signingParams!); setWeb3(web3Local); }; if (signingParams) { @@ -127,12 +130,12 @@ function App() { const retrieveSharesResponse = await (tKey.serviceProvider as TorusServiceProvider).directWeb.getTorusKey(verifier, verifier_id, { verifier_id }, idToken) - const signatures: any = retrieveSharesResponse.sessionData.sessionTokenData.filter(i => Boolean(i)).map((session) => JSON.stringify({ data: session.token, sig: session.signature })); + const signatures: string[] = retrieveSharesResponse.sessionData.sessionTokenData.filter(i => Boolean(i)).map((session) => JSON.stringify({ data: session.token, sig: session.signature })); const OAuthShare = new BN(TorusUtils.getPostboxKey(retrieveSharesResponse), "hex"); - (tKey.serviceProvider as any).postboxKey = OAuthShare; - (tKey.serviceProvider as any).verifierName = verifier; - (tKey.serviceProvider as any).verifierId = verifier_id; + (tKey.serviceProvider as TorusServiceProvider).postboxKey = OAuthShare; + (tKey.serviceProvider as TorusServiceProvider).verifierName = verifier; + (tKey.serviceProvider as TorusServiceProvider).verifierId = verifier_id; const loginResponse = { userInfo: parsedToken, @@ -195,7 +198,7 @@ function App() { content: 'input' as any, }).then(async value => { uiConsole(value); - return await (tKey.modules.shareSerialization as any).deserialize(value, "mnemonic"); + return await (tKey.modules.shareSerialization as ShareSerializationModule).deserialize(value, "mnemonic"); }); } catch (error) { uiConsole(error); @@ -319,7 +322,7 @@ function App() { const { tssShare: tssShare2, tssIndex: tssIndex2 } = await tKey.getTSSShare(localFactorKey); await addFactorKeyMetadata(tKey, backupFactorKey, tssShare2, tssIndex2, "manual share"); - const serializedShare = await (tKey.modules.shareSerialization as any).serialize(backupFactorKey, "mnemonic"); + const serializedShare = await (tKey.modules.shareSerialization as ShareSerializationModule).serialize(backupFactorKey, "mnemonic"); await tKey.syncLocalMetadataTransitions(); uiConsole("Successfully created manual backup. Manual Backup Factor: ", serializedShare) @@ -352,12 +355,12 @@ function App() { }); } uiConsole("backupFactorIndex:", backupFactorIndex + 1); - await addNewTSSShareAndFactor(tKey, backupFactorPub, backupFactorIndex + 1, localFactorKey, signingParams.signatures); + await addNewTSSShareAndFactor(tKey, backupFactorPub, backupFactorIndex + 1, localFactorKey, signingParams!.signatures); console.log("backupFactorKey:", backupFactorKey.toString("hex")); const { tssShare: tssShare2, tssIndex: tssIndex2 } = await tKey.getTSSShare(backupFactorKey); await addFactorKeyMetadata(tKey, backupFactorKey, tssShare2, tssIndex2, "manual share"); - const serializedShare = await (tKey.modules.shareSerialization as any).serialize(backupFactorKey, "mnemonic"); + const serializedShare = await (tKey.modules.shareSerialization as ShareSerializationModule).serialize(backupFactorKey, "mnemonic"); await tKey._syncShareMetadata(); await tKey.syncLocalMetadataTransitions(); uiConsole(" Successfully created manual backup.Manual Backup Factor: ", serializedShare); @@ -368,7 +371,7 @@ function App() { } const deleteTkeyLocalStore = async () => { - localStorage.removeItem(`tKeyLocalStore\u001c${loginResponse.verifier}\u001c${loginResponse.verifier_id}`); + localStorage.removeItem(`tKeyLocalStore\u001c${loginResponse!.verifier}\u001c${loginResponse!.verifier_id}`); uiConsole("Successfully deleted tKey local store"); } @@ -399,21 +402,21 @@ function App() { return user; }; - const getLoginResponse = (): void => { + const getLoginResponse = (): LoginResponse => { uiConsole(loginResponse); - return loginResponse; + return loginResponse!; }; - const getMetadataKey = (): void => { + const getMetadataKey = (): string => { uiConsole(metadataKey); - return metadataKey; + return metadataKey!; }; const resetAccount = async () => { try { - localStorage.removeItem(`tKeyLocalStore\u001c${loginResponse.verifier}\u001c${loginResponse.verifier_id}`); + localStorage.removeItem(`tKeyLocalStore\u001c${loginResponse!.verifier}\u001c${loginResponse!.verifier_id}`); await tKey.storageLayer.setMetadata({ - privKey: oAuthShare, + privKey: oAuthShare!, input: { message: "KEY_NOT_FOUND" }, }); uiConsole("Reset Account Successful."); diff --git a/mpc-core-kit/tkey-mpc-react-firebase-example/src/tkey.ts b/mpc-core-kit/tkey-mpc-react-firebase-example/src/tkey.ts index 654dd02a..a223e3c7 100644 --- a/mpc-core-kit/tkey-mpc-react-firebase-example/src/tkey.ts +++ b/mpc-core-kit/tkey-mpc-react-firebase-example/src/tkey.ts @@ -2,12 +2,13 @@ import ThresholdKey from "@tkey-mpc/core"; import { TorusServiceProvider } from "@tkey-mpc/service-provider-torus"; import { TorusStorageLayer } from "@tkey-mpc/storage-layer-torus"; import { ShareSerializationModule } from "@tkey-mpc/share-serialization"; +import { CustomChainConfig } from "@web3auth/base"; // Configuration of Service Provider const web3AuthClientId = "BEglQSgt4cUWcj6SKRdu5QkOXTsePmMcusG5EAoyjyOYKlVRjIF1iCNnMOTfpzCiunHRrMui8TIwQPXdkQ8Yxuk"; // get from https://dashboard.web3auth.io -export const chainConfig = { +export const chainConfig: Omit = { chainId: "0x5", rpcTarget: "https://rpc.ankr.com/eth_goerli", displayName: "Goerli Testnet", diff --git a/mpc-core-kit/tkey-mpc-react-firebase-example/src/utils.ts b/mpc-core-kit/tkey-mpc-react-firebase-example/src/utils.ts index 46c56a5f..5ed2ad05 100644 --- a/mpc-core-kit/tkey-mpc-react-firebase-example/src/utils.ts +++ b/mpc-core-kit/tkey-mpc-react-firebase-example/src/utils.ts @@ -1,5 +1,5 @@ import BN from "bn.js"; -import { encrypt, getPubKeyECC, Point, randomSelection, ShareStore } from "@tkey-mpc/common-types"; +import { encrypt, getPubKeyECC, Point, PointHex, randomSelection, ShareStore } from "@tkey-mpc/common-types"; import EC from "elliptic"; import { generatePrivate } from "@toruslabs/eccrypto"; @@ -10,8 +10,32 @@ import keccak256 from "keccak256"; import Web3 from "web3"; import type { provider } from "web3-core"; import { utils } from "@toruslabs/tss-client"; +import { CustomChainConfig } from "@web3auth/base"; +import ThresholdKey from "@tkey-mpc/core/dist/types/core"; + const { getDKLSCoeff, setupSockets } = utils; +export type LoginResponse = { + userInfo: any, + verifier: string, + verifier_id: string, + signatures : string[], + OAuthShare: BN, +} + +export type SigningParams = { + tssNonce: number, + tssShare2: BN, + tssShare2Index: number, + compressedTSSPubKey: Buffer, + signatures: string[], + nodeDetails : { + serverEndpoints: string[]; + serverPubKeys: PointHex[]; + serverThreshold: number; + }, +} + const parties = 4; const clientIndex = parties - 1; const tssImportUrl = `https://sapphire-dev-2-2.authnetwork.dev/tss/v1/clientWasm`; @@ -24,7 +48,7 @@ const DELIMITERS = { }; -export function getEcCrypto(): any { +export function getEcCrypto(): EC.ec { // eslint-disable-next-line new-cap return new EC.ec("secp256k1"); } @@ -47,7 +71,7 @@ export const generateTSSEndpoints = (tssNodeEndpoints: string[], parties: number return { endpoints, tssWSEndpoints, partyIndexes }; }; -export const setupWeb3 = async (chainConfig: any, loginReponse: any, signingParams: any) => { +export const setupWeb3 = async (chainConfig: Omit, loginReponse: LoginResponse, signingParams: SigningParams) => { try { const ethereumSigningProvider = new EthereumSigningProvider({ config: { @@ -145,7 +169,7 @@ export type FactorKeyCloudMetadata = { tssIndex: number; }; -const fetchDeviceShareFromTkey = async (tKey: any) => { +const fetchDeviceShareFromTkey = async (tKey: ThresholdKey) => { if (!tKey) { console.error("tKey not initialized yet"); return; @@ -168,7 +192,7 @@ const fetchDeviceShareFromTkey = async (tKey: any) => { }; -export const addFactorKeyMetadata = async (tKey: any, factorKey: BN, tssShare: BN, tssIndex: number, factorKeyDescription: string) => { +export const addFactorKeyMetadata = async (tKey: ThresholdKey, factorKey: BN, tssShare: BN, tssIndex: number, factorKeyDescription: string) => { if (!tKey) { console.error("tKey not initialized yet"); return; @@ -202,11 +226,11 @@ export const addFactorKeyMetadata = async (tKey: any, factorKey: BN, tssShare: B await tKey.addShareDescription(factorIndex, JSON.stringify(params), true); }; -export const gettKeyLocalStore = (loginResponse: any) => { +export const gettKeyLocalStore = (loginResponse: LoginResponse) => { return JSON.parse(localStorage.getItem(`tKeyLocalStore\u001c${loginResponse.verifier}\u001c${loginResponse.verifier_id}`) || "{}"); } -export const settKeyLocalStore = (loginResponse: any, localFactorKey: BN) => { +export const settKeyLocalStore = (loginResponse: LoginResponse, localFactorKey: BN) => { localStorage.setItem(`tKeyLocalStore\u001c${loginResponse.verifier}\u001c${loginResponse.verifier_id}`, JSON.stringify({ factorKey: localFactorKey.toString("hex"), verifier: loginResponse.verifier, @@ -214,7 +238,7 @@ export const settKeyLocalStore = (loginResponse: any, localFactorKey: BN) => { })); } -export const copyExistingTSSShareForNewFactor = async (tKey: any, newFactorPub: Point, factorKeyForExistingTSSShare: BN) => { +export const copyExistingTSSShareForNewFactor = async (tKey: ThresholdKey, newFactorPub: Point, factorKeyForExistingTSSShare: BN) => { if (!tKey) { throw new Error("tkey does not exist, cannot copy factor pub"); } @@ -251,7 +275,7 @@ export const copyExistingTSSShareForNewFactor = async (tKey: any, newFactorPub: }); }; -export const addNewTSSShareAndFactor = async (tKey: any, newFactorPub: Point, newFactorTSSIndex: number, factorKeyForExistingTSSShare: BN, signatures: any) => { +export const addNewTSSShareAndFactor = async (tKey: ThresholdKey, newFactorPub: Point, newFactorTSSIndex: number, factorKeyForExistingTSSShare: BN, signatures: string[]) => { try { if (!tKey) { throw new Error("tkey does not exist, cannot add factor pub"); @@ -265,7 +289,7 @@ export const addNewTSSShareAndFactor = async (tKey: any, newFactorPub: Point, ne const existingFactorPubs = tKey.metadata.factorPubs[tKey.tssTag].slice(); const updatedFactorPubs = existingFactorPubs.concat([newFactorPub]); - const existingTSSIndexes = existingFactorPubs.map((fb: any) => tKey.getFactorEncs(fb).tssIndex); + const existingTSSIndexes = existingFactorPubs.map((fb: Point) => tKey.getFactorEncs(fb).tssIndex); const updatedTSSIndexes = existingTSSIndexes.concat([newFactorTSSIndex]); const { tssShare, tssIndex } = await tKey.getTSSShare(factorKeyForExistingTSSShare); diff --git a/mpc-core-kit/tkey-mpc-react-popup-example/src/App.tsx b/mpc-core-kit/tkey-mpc-react-popup-example/src/App.tsx index e29f0b37..1634ba96 100644 --- a/mpc-core-kit/tkey-mpc-react-popup-example/src/App.tsx +++ b/mpc-core-kit/tkey-mpc-react-popup-example/src/App.tsx @@ -1,18 +1,21 @@ import "./App.css"; import TorusUtils from "@toruslabs/torus.js"; - import { getPubKeyPoint } from "@tkey-mpc/common-types"; import BN from "bn.js"; import { generatePrivate } from "eccrypto"; import { useEffect, useState } from "react"; import swal from "sweetalert"; import { tKey } from "./tkey"; -import { addFactorKeyMetadata, setupWeb3, copyExistingTSSShareForNewFactor, addNewTSSShareAndFactor, getEcCrypto } from "./utils"; +import { addFactorKeyMetadata, setupWeb3, copyExistingTSSShareForNewFactor, addNewTSSShareAndFactor, getEcCrypto, LoginResponse, SigningParams } from "./utils"; import { utils } from "@toruslabs/tss-client"; +import { ShareSerializationModule } from "@tkey-mpc/share-serialization"; +import Web3 from "web3"; +import { TorusServiceProvider } from "@tkey-mpc/service-provider-torus"; +import { TorusLoginResponse } from "@toruslabs/customauth" +import { CustomChainConfig } from "@web3auth/base"; const { getTSSPubKey } = utils; - const uiConsole = (...args: any[]): void => { const el = document.querySelector("#console>p"); if (el) { @@ -21,21 +24,29 @@ const uiConsole = (...args: any[]): void => { console.log(...args); }; +const chainConfig: Omit = { + chainId: "0x5", + rpcTarget: "https://rpc.ankr.com/eth_goerli", + displayName: "Goerli Testnet", + blockExplorer: "https://goerli.etherscan.io", + ticker: "ETH", + tickerName: "Ethereum", +} function App() { - const [loginResponse, setLoginResponse] = useState(null); + const [loginResponse, setLoginResponse] = useState(null); const [user, setUser] = useState(null); - const [metadataKey, setMetadataKey] = useState(); + const [metadataKey, setMetadataKey] = useState(null); const [localFactorKey, setLocalFactorKey] = useState(null); - const [oAuthShare, setOAuthShare] = useState(null); - const [web3, setWeb3] = useState(null); - const [signingParams, setSigningParams] = useState(null); + const [oAuthShare, setOAuthShare] = useState(null); + const [web3, setWeb3] = useState(null); + const [signingParams, setSigningParams] = useState(null); useEffect(() => { const init = async () => { // Initialization of Service Provider try { - await (tKey.serviceProvider as any).init(); + await (tKey.serviceProvider as TorusServiceProvider).init({}); } catch (error) { console.error(error); } @@ -46,32 +57,26 @@ function App() { useEffect(() => { if (!localFactorKey) return; localStorage.setItem( - `tKeyLocalStore\u001c${loginResponse.userInfo.verifier}\u001c${loginResponse.userInfo.verifierId}`, + `tKeyLocalStore\u001c${loginResponse!.userInfo.verifier}\u001c${loginResponse!.userInfo.verifierId}`, JSON.stringify({ factorKey: localFactorKey.toString("hex"), - verifier: loginResponse.userInfo.verifier, - verifierId: loginResponse.userInfo.verifierId, + verifier: loginResponse!.userInfo.verifier, + verifierId: loginResponse!.userInfo.verifierId, }) ); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [localFactorKey]); // sets up web3 useEffect(() => { const localSetup = async () => { - const chainConfig = { - chainId: "0x5", - rpcTarget: "https://rpc.ankr.com/eth_goerli", - displayName: "Goerli Testnet", - blockExplorer: "https://goerli.etherscan.io", - ticker: "ETH", - tickerName: "Ethereum", - } - const web3Local = await setupWeb3(chainConfig, loginResponse, signingParams); + const web3Local = await setupWeb3(chainConfig, loginResponse!, signingParams!); setWeb3(web3Local); }; if (signingParams) { localSetup(); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [signingParams]); const triggerLogin = async () => { @@ -81,17 +86,15 @@ function App() { } try { // Triggering Login using Service Provider ==> opens the popup - const loginResponse = await (tKey.serviceProvider as any).triggerLogin({ + const loginRes = await (tKey.serviceProvider as TorusServiceProvider).triggerLogin({ typeOfLogin: 'google', verifier: 'google-tkey-w3a', clientId: '774338308167-q463s7kpvja16l4l0kko3nb925ikds2p.apps.googleusercontent.com', }); - console.log("loginResponse", loginResponse); - setLoginResponse(loginResponse); - setUser(loginResponse.userInfo); - return loginResponse; + setUser(loginRes.userInfo); + return loginRes; } catch (error) { uiConsole(error); } @@ -103,14 +106,30 @@ function App() { return; } try { - const loginResponse = await triggerLogin(); // Calls the triggerLogin() function above + const loginRes: TorusLoginResponse | undefined = await triggerLogin(); // Calls the triggerLogin() function above - const OAuthShare = new BN(TorusUtils.getPostboxKey(loginResponse), "hex"); + if (!loginRes) { + throw new Error("Login response not found"); + } + + const OAuthShare: BN = new BN(TorusUtils.getPostboxKey(loginRes), "hex"); setOAuthShare(OAuthShare); //@ts-ignore - const signatures = loginResponse.sessionData.sessionTokenData.filter(i => Boolean(i)).map((session) => JSON.stringify({ data: session.token, sig: session.signature })); + const signatures: string[] = loginRes.sessionData.sessionTokenData.filter(i => Boolean(i)).map((session) => JSON.stringify({ data: session.token, sig: session.signature })); - const tKeyLocalStoreString = localStorage.getItem(`tKeyLocalStore\u001c${loginResponse.userInfo.verifier}\u001c${loginResponse.userInfo.verifierId}`); + + const loginResponse: LoginResponse = { + userInfo: loginRes.userInfo, + verifier: loginRes.userInfo.verifier, + verifier_id: loginRes.userInfo.verifierId, + signatures, + OAuthShare, + } + + console.log("loginResponse", loginResponse); + + setLoginResponse(loginResponse); + const tKeyLocalStoreString = localStorage.getItem(`tKeyLocalStore\u001c${loginResponse.verifier}\u001c${loginResponse.verifier_id}`); const tKeyLocalStore = JSON.parse(tKeyLocalStoreString || "{}"); let factorKey: BN | null = null; @@ -124,7 +143,7 @@ function App() { const factorPub = getPubKeyPoint(factorKey); await tKey.initialize({ useTSS: true, factorPub, deviceTSSShare, deviceTSSIndex }); } else { - if (tKeyLocalStore.verifier === loginResponse.userInfo.verifier && tKeyLocalStore.verifierId === loginResponse.userInfo.verifierId) { + if (tKeyLocalStore.verifier === loginResponse.verifier && tKeyLocalStore.verifierId === loginResponse.verifier_id) { factorKey = new BN(tKeyLocalStore.factorKey, "hex"); } else { @@ -133,7 +152,7 @@ function App() { content: 'input' as any, }).then(async value => { uiConsole(value); - return await (tKey.modules.shareSerialization as any).deserialize(value, "mnemonic"); + return await (tKey.modules.shareSerialization as ShareSerializationModule).deserialize(value, "mnemonic"); }); } catch (error) { uiConsole(error); @@ -190,7 +209,7 @@ function App() { // 5. save factor key and other metadata if ( !existingUser || - !(tKeyLocalStore.verifier === loginResponse.userInfo.verifier && tKeyLocalStore.verifierId === loginResponse.userInfo.verifierId) + !(tKeyLocalStore.verifier === loginResponse.verifier && tKeyLocalStore.verifierId === loginResponse.verifier_id) ) { await addFactorKeyMetadata(tKey, factorKey, tssShare2, tssShare2Index, "local storage share"); } @@ -253,7 +272,7 @@ function App() { const { tssShare: tssShare2, tssIndex: tssIndex2 } = await tKey.getTSSShare(localFactorKey); await addFactorKeyMetadata(tKey, backupFactorKey, tssShare2, tssIndex2, "manual share"); - const serializedShare = await (tKey.modules.shareSerialization as any).serialize(backupFactorKey, "mnemonic"); + const serializedShare = await (tKey.modules.shareSerialization as ShareSerializationModule).serialize(backupFactorKey, "mnemonic"); await tKey.syncLocalMetadataTransitions(); uiConsole("Successfully created manual backup. Manual Backup Factor: ", serializedShare) @@ -285,11 +304,11 @@ function App() { }); } uiConsole("backupFactorIndex:", backupFactorIndex + 1); - await addNewTSSShareAndFactor(tKey, backupFactorPub, backupFactorIndex + 1, localFactorKey, signingParams.signatures); + await addNewTSSShareAndFactor(tKey, backupFactorPub, backupFactorIndex + 1, localFactorKey, signingParams!.signatures); const { tssShare: tssShare2, tssIndex: tssIndex2 } = await tKey.getTSSShare(backupFactorKey); await addFactorKeyMetadata(tKey, backupFactorKey, tssShare2, tssIndex2, "manual share"); - const serializedShare = await (tKey.modules.shareSerialization as any).serialize(backupFactorKey, "mnemonic"); + const serializedShare = await (tKey.modules.shareSerialization as ShareSerializationModule).serialize(backupFactorKey, "mnemonic"); await tKey.syncLocalMetadataTransitions(); uiConsole(" Successfully created manual backup.Manual Backup Factor: ", serializedShare); @@ -300,7 +319,7 @@ function App() { } const deleteTkeyLocalStore = async () => { - localStorage.removeItem(`tKeyLocalStore\u001c${loginResponse.userInfo.verifier}\u001c${loginResponse.userInfo.verifierId}`); + localStorage.removeItem(`tKeyLocalStore\u001c${loginResponse!.verifier}\u001c${loginResponse!.verifier_id}`); uiConsole("Successfully deleted tKey local store"); } @@ -331,21 +350,21 @@ function App() { return user; }; - const getLoginResponse = (): void => { + const getLoginResponse = (): LoginResponse => { uiConsole(loginResponse); - return loginResponse; + return loginResponse!; }; - const getMetadataKey = (): void => { + const getMetadataKey = (): string => { uiConsole(metadataKey); - return metadataKey; + return metadataKey!; }; const resetAccount = async () => { try { - localStorage.removeItem(`tKeyLocalStore\u001c${loginResponse.userInfo.verifier}\u001c${loginResponse.userInfo.verifierId}`); + localStorage.removeItem(`tKeyLocalStore\u001c${loginResponse!.verifier}\u001c${loginResponse!.verifier_id}`); await tKey.storageLayer.setMetadata({ - privKey: oAuthShare, + privKey: oAuthShare!, input: { message: "KEY_NOT_FOUND" }, }); uiConsole("Reset Account Successful."); diff --git a/mpc-core-kit/tkey-mpc-react-popup-example/src/utils.ts b/mpc-core-kit/tkey-mpc-react-popup-example/src/utils.ts index eb54fab4..5ed2ad05 100644 --- a/mpc-core-kit/tkey-mpc-react-popup-example/src/utils.ts +++ b/mpc-core-kit/tkey-mpc-react-popup-example/src/utils.ts @@ -1,5 +1,5 @@ import BN from "bn.js"; -import { encrypt, getPubKeyECC, Point, randomSelection, ShareStore } from "@tkey-mpc/common-types"; +import { encrypt, getPubKeyECC, Point, PointHex, randomSelection, ShareStore } from "@tkey-mpc/common-types"; import EC from "elliptic"; import { generatePrivate } from "@toruslabs/eccrypto"; @@ -10,8 +10,32 @@ import keccak256 from "keccak256"; import Web3 from "web3"; import type { provider } from "web3-core"; import { utils } from "@toruslabs/tss-client"; +import { CustomChainConfig } from "@web3auth/base"; +import ThresholdKey from "@tkey-mpc/core/dist/types/core"; + const { getDKLSCoeff, setupSockets } = utils; +export type LoginResponse = { + userInfo: any, + verifier: string, + verifier_id: string, + signatures : string[], + OAuthShare: BN, +} + +export type SigningParams = { + tssNonce: number, + tssShare2: BN, + tssShare2Index: number, + compressedTSSPubKey: Buffer, + signatures: string[], + nodeDetails : { + serverEndpoints: string[]; + serverPubKeys: PointHex[]; + serverThreshold: number; + }, +} + const parties = 4; const clientIndex = parties - 1; const tssImportUrl = `https://sapphire-dev-2-2.authnetwork.dev/tss/v1/clientWasm`; @@ -24,7 +48,7 @@ const DELIMITERS = { }; -export function getEcCrypto(): any { +export function getEcCrypto(): EC.ec { // eslint-disable-next-line new-cap return new EC.ec("secp256k1"); } @@ -47,7 +71,7 @@ export const generateTSSEndpoints = (tssNodeEndpoints: string[], parties: number return { endpoints, tssWSEndpoints, partyIndexes }; }; -export const setupWeb3 = async (chainConfig: any, loginReponse: any, signingParams: any) => { +export const setupWeb3 = async (chainConfig: Omit, loginReponse: LoginResponse, signingParams: SigningParams) => { try { const ethereumSigningProvider = new EthereumSigningProvider({ config: { @@ -57,7 +81,7 @@ export const setupWeb3 = async (chainConfig: any, loginReponse: any, signingPara const { tssNonce, tssShare2, tssShare2Index, compressedTSSPubKey, signatures, nodeDetails } = signingParams; - const { verifier, verifierId } = loginReponse.userInfo; + const { verifier, verifier_id: verifierId } = loginReponse; const vid = `${verifier}${DELIMITERS.Delimiter1}${verifierId}`; const sessionId = `${vid}${DELIMITERS.Delimiter2}default${DELIMITERS.Delimiter3}${tssNonce}${DELIMITERS.Delimiter4}`; @@ -77,6 +101,7 @@ export const setupWeb3 = async (chainConfig: any, loginReponse: any, signingPara // 1. setup // generate endpoints for servers + const { endpoints, tssWSEndpoints, partyIndexes } = generateTSSEndpoints(nodeDetails.serverEndpoints, parties, clientIndex); // setup mock shares, sockets and tss wasm files. @@ -144,7 +169,7 @@ export type FactorKeyCloudMetadata = { tssIndex: number; }; -const fetchDeviceShareFromTkey = async (tKey: any) => { +const fetchDeviceShareFromTkey = async (tKey: ThresholdKey) => { if (!tKey) { console.error("tKey not initialized yet"); return; @@ -167,7 +192,7 @@ const fetchDeviceShareFromTkey = async (tKey: any) => { }; -export const addFactorKeyMetadata = async (tKey: any, factorKey: BN, tssShare: BN, tssIndex: number, factorKeyDescription: string) => { +export const addFactorKeyMetadata = async (tKey: ThresholdKey, factorKey: BN, tssShare: BN, tssIndex: number, factorKeyDescription: string) => { if (!tKey) { console.error("tKey not initialized yet"); return; @@ -201,7 +226,19 @@ export const addFactorKeyMetadata = async (tKey: any, factorKey: BN, tssShare: B await tKey.addShareDescription(factorIndex, JSON.stringify(params), true); }; -export const copyExistingTSSShareForNewFactor = async (tKey: any, newFactorPub: Point, factorKeyForExistingTSSShare: BN) => { +export const gettKeyLocalStore = (loginResponse: LoginResponse) => { + return JSON.parse(localStorage.getItem(`tKeyLocalStore\u001c${loginResponse.verifier}\u001c${loginResponse.verifier_id}`) || "{}"); +} + +export const settKeyLocalStore = (loginResponse: LoginResponse, localFactorKey: BN) => { + localStorage.setItem(`tKeyLocalStore\u001c${loginResponse.verifier}\u001c${loginResponse.verifier_id}`, JSON.stringify({ + factorKey: localFactorKey.toString("hex"), + verifier: loginResponse.verifier, + verifierId: loginResponse.verifier_id, + })); +} + +export const copyExistingTSSShareForNewFactor = async (tKey: ThresholdKey, newFactorPub: Point, factorKeyForExistingTSSShare: BN) => { if (!tKey) { throw new Error("tkey does not exist, cannot copy factor pub"); } @@ -238,7 +275,7 @@ export const copyExistingTSSShareForNewFactor = async (tKey: any, newFactorPub: }); }; -export const addNewTSSShareAndFactor = async (tKey: any, newFactorPub: Point, newFactorTSSIndex: number, factorKeyForExistingTSSShare: BN, signatures: any) => { +export const addNewTSSShareAndFactor = async (tKey: ThresholdKey, newFactorPub: Point, newFactorTSSIndex: number, factorKeyForExistingTSSShare: BN, signatures: string[]) => { try { if (!tKey) { throw new Error("tkey does not exist, cannot add factor pub"); @@ -252,7 +289,7 @@ export const addNewTSSShareAndFactor = async (tKey: any, newFactorPub: Point, ne const existingFactorPubs = tKey.metadata.factorPubs[tKey.tssTag].slice(); const updatedFactorPubs = existingFactorPubs.concat([newFactorPub]); - const existingTSSIndexes = existingFactorPubs.map((fb: any) => tKey.getFactorEncs(fb).tssIndex); + const existingTSSIndexes = existingFactorPubs.map((fb: Point) => tKey.getFactorEncs(fb).tssIndex); const updatedTSSIndexes = existingTSSIndexes.concat([newFactorTSSIndex]); const { tssShare, tssIndex } = await tKey.getTSSShare(factorKeyForExistingTSSShare);