From 924d68ce12c9dbf1dfd99f561167332d75186c72 Mon Sep 17 00:00:00 2001 From: ieow Date: Fri, 1 Nov 2024 13:34:24 +0800 Subject: [PATCH] feat: toJson, fromJson --- src/mpcCoreKit.ts | 71 ++++++++++++++++++++++++++++++++++------- tests/ed25519.spec.ts | 1 + tests/serialize.spec.ts | 24 ++++++++++++++ tests/setup.ts | 21 ++++++++++-- 4 files changed, 104 insertions(+), 13 deletions(-) create mode 100644 tests/serialize.spec.ts diff --git a/src/mpcCoreKit.ts b/src/mpcCoreKit.ts index 4ea24604..59378052 100644 --- a/src/mpcCoreKit.ts +++ b/src/mpcCoreKit.ts @@ -1,6 +1,5 @@ import { BNString, KeyType, Point, secp256k1, SHARE_DELETED, ShareStore, StringifiedType } from "@tkey/common-types"; import { CoreError } from "@tkey/core"; -import { ShareSerializationModule } from "@tkey/share-serialization"; import { TorusStorageLayer } from "@tkey/storage-layer-torus"; import { factorKeyCurve, getPubKeyPoint, lagrangeInterpolation, TKeyTSS, TSSTorusServiceProvider } from "@tkey/tss"; import { KEY_TYPE, SIGNER_MAP } from "@toruslabs/constants"; @@ -115,7 +114,10 @@ export class Web3AuthMPCCoreKit implements ICoreKit { if (options.enableLogging) { log.enableAll(); this.enableLogging = true; - } else log.setLevel("error"); + } else { + log.setLevel("error"); + options.enableLogging = false; + } if (typeof options.manualSync !== "boolean") options.manualSync = false; if (!options.web3AuthNetwork) options.web3AuthNetwork = WEB3AUTH_NETWORK.MAINNET; if (!options.sessionTime) options.sessionTime = 86400; @@ -129,6 +131,10 @@ export class Web3AuthMPCCoreKit implements ICoreKit { this.options = options as Web3AuthOptionsWithDefaults; this.currentStorage = new AsyncStorage(this._storageBaseKey, options.storage); + + this.sessionManager = new SessionManager({ + sessionTime: this.options.sessionTime, + }); } get tKey(): TKeyTSS { @@ -190,6 +196,57 @@ export class Web3AuthMPCCoreKit implements ICoreKit { return this.keyType === KeyType.ed25519 && this.options.useClientGeneratedTSSKey === undefined ? true : !!this.options.useClientGeneratedTSSKey; } + static async fromJSON(value: StringifiedType, options: Web3AuthOptions): Promise { + const coreKit = new Web3AuthMPCCoreKit(options); + const { state, serviceProvider, storageLayer, keyType, atomicCallStackCounter, ready, sessionId, tkey } = value; + coreKit.torusSp = TSSTorusServiceProvider.fromJSON(serviceProvider); + coreKit.storageLayer = TorusStorageLayer.fromJSON(storageLayer); + + coreKit.tkey = await TKeyTSS.fromJSON(tkey, { + serviceProvider: coreKit.torusSp, + storageLayer: coreKit.storageLayer, + enableLogging: options.enableLogging, + tssKeyType: options.tssLib.keyType as KeyType, + }); + await coreKit.tkey.reconstructKey(); + + if (state.factorKey) state.factorKey = new BN(state.factorKey, "hex"); + if (state.tssPubKey) state.tssPubKey = Buffer.from(state.tssPubKey, "hex"); + coreKit.state = state; + coreKit.sessionManager.sessionId = sessionId; + coreKit.atomicCallStackCounter = atomicCallStackCounter; + coreKit.ready = ready; + + if (coreKit._keyType !== keyType) { + console.log("keyType mismatch", coreKit._keyType, keyType); + throw CoreKitError.invalidConfig(); + } + + // will be derived from option during constructor + // sessionManager + // enableLogging + // private _tssLib: TssLibType; + // private wasmLib: DKLSWasmLib | FrostWasmLib; + // private _keyType: KeyType; + return coreKit; + } + + public toJSON(): StringifiedType { + const factorKey = this.state.factorKey ? this.state.factorKey.toString("hex") : undefined; + const tssPubKey = this.state.tssPubKey ? this.state.tssPubKey.toString("hex") : undefined; + return { + state: { ...this.state, factorKey, tssPubKey }, + options: this.options, + serviceProvider: this.torusSp.toJSON(), + storageLayer: this.storageLayer.toJSON(), + tkey: this.tKey.toJSON(), + keyType: this.keyType, + sessionId: this.sessionManager.sessionId, + atomicCallStackCounter: this.atomicCallStackCounter, + ready: this.ready, + }; + } + // RecoverTssKey only valid for user that enable MFA where user has 2 type shares : // TssShareType.DEVICE and TssShareType.RECOVERY // if the factors key provided is the same type recovery will not works @@ -249,16 +306,11 @@ export class Web3AuthMPCCoreKit implements ICoreKit { enableLogging: this.enableLogging, }); - const shareSerializationModule = new ShareSerializationModule(); - this.tkey = new TKeyTSS({ enableLogging: this.enableLogging, serviceProvider: this.torusSp, storageLayer: this.storageLayer, manualSync: this.options.manualSync, - modules: { - shareSerialization: shareSerializationModule, - }, tssKeyType: this.keyType, }); @@ -272,10 +324,7 @@ export class Web3AuthMPCCoreKit implements ICoreKit { // setup session Manager during init instead of async constructor const sessionId = await this.currentStorage.get("sessionId"); - this.sessionManager = new SessionManager({ - sessionTime: this.options.sessionTime, - sessionId, - }); + this.sessionManager.sessionId = sessionId; // try handle redirect flow if enabled and return(redirect) from oauth login if ( diff --git a/tests/ed25519.spec.ts b/tests/ed25519.spec.ts index 208beb5a..d9b723e0 100644 --- a/tests/ed25519.spec.ts +++ b/tests/ed25519.spec.ts @@ -144,6 +144,7 @@ variable.forEach((testVariable) => { const msgBuffer = Buffer.from(msg); const signature = ed25519().makeSignature((await coreKitInstance.sign(msgBuffer)).toString("hex")); + msgBuffer.slice(1,2); const valid = ed25519().verify(msgBuffer, signature, coreKitInstance.getPubKeyEd25519()); assert(valid); }); diff --git a/tests/serialize.spec.ts b/tests/serialize.spec.ts new file mode 100644 index 00000000..3e55083f --- /dev/null +++ b/tests/serialize.spec.ts @@ -0,0 +1,24 @@ +import { describe, it } from "node:test"; +import { defaultTestOptions, newCoreKitLogInInstance } from "./setup"; +import { AsyncStorage, MemoryStorage, WEB3AUTH_NETWORK, Web3AuthMPCCoreKit } from "src"; +import { deepEqual, deepStrictEqual, equal, strictEqual } from "node:assert"; + + +describe('serialize deserialze mpc corekit', () => { + it('serialize', async () => { + const localMemoryStorage = new MemoryStorage(); + const instance = await newCoreKitLogInInstance({ + network: WEB3AUTH_NETWORK.DEVNET, + manualSync: true, + email: "a@b.com", + storageInstance: localMemoryStorage, + }) + const options = defaultTestOptions({ network: WEB3AUTH_NETWORK.DEVNET, manualSync: true, storageInstance: localMemoryStorage }); + const serialized = JSON.stringify(instance); + console.log(serialized) + const deserialized = await Web3AuthMPCCoreKit.fromJSON(JSON.parse(serialized), options); + + + + }); +}); diff --git a/tests/setup.ts b/tests/setup.ts index ed768178..ed97b602 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -4,7 +4,7 @@ import BN from "bn.js"; import jwt, { Algorithm } from "jsonwebtoken"; import { tssLib as tssLibDKLS } from "@toruslabs/tss-dkls-lib"; -import { IAsyncStorage, IStorage, parseToken, TssLib, WEB3AUTH_NETWORK_TYPE, Web3AuthMPCCoreKit } from "../src"; +import { IAsyncStorage, IStorage, parseToken, TssLibType, WEB3AUTH_NETWORK_TYPE, Web3AuthMPCCoreKit, Web3AuthOptions } from "../src"; export const mockLogin2 = async (email: string) => { const req = new Request("https://li6lnimoyrwgn2iuqtgdwlrwvq0upwtr.lambda-url.eu-west-1.on.aws/", { @@ -84,6 +84,23 @@ export const mockLogin = async (email?: string) => { }; export type LoginFunc = (email: string) => Promise<{ idToken: string, parsedToken: any }>; +export const defaultTestOptions = (params: { + network: WEB3AUTH_NETWORK_TYPE; + manualSync: boolean; + storageInstance: IStorage | IAsyncStorage; + tssLib?: TssLibType; +}) : Web3AuthOptions => { + const { network, manualSync, storageInstance, tssLib } = params; + return { + web3AuthClientId: "torus-key-test", + web3AuthNetwork: network, + baseUrl: "http://localhost:3000", + uxMode: "nodejs", + tssLib: tssLib || tssLibDKLS, + storage: storageInstance, + manualSync, + } +} export const newCoreKitLogInInstance = async ({ network, @@ -97,7 +114,7 @@ export const newCoreKitLogInInstance = async ({ manualSync: boolean; email: string; storageInstance: IStorage | IAsyncStorage; - tssLib?: TssLib; + tssLib?: TssLibType; importTssKey?: string; login?: LoginFunc; }) => {