@idos-network/enclave 1.2.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys-P2XLU3qP.mjs","names":[],"sources":["../src/base.ts","../src/keys.ts"],"sourcesContent":["import type { idOSCredentialRecord as idOSCredential } from \"@idos-network/credentials/types\";\n\nimport { recordFilter } from \"@idos-network/credentials/utils\";\nimport { base64Decode, fromBytesToJson, hexEncode } from \"@idos-network/utils/codecs\";\n\nimport type {\n AddAddressMessageToSign,\n AddAddressSignatureMessage,\n RemoveAddressMessageToSign,\n RemoveAddressSignatureMessage,\n} from \"./mpc/types\";\nimport type { EnclaveOptions, PublicEncryptionProfile } from \"./types\";\n\nexport abstract class BaseProvider<K extends EnclaveOptions = EnclaveOptions> {\n readonly options: K;\n\n // oxlint-disable-next-line typescript/no-explicit-any -- TODO: Change this when we know how to MPC & other chains\n protected _signMethod?: (domain: any, types: any, value: any) => Promise<string>;\n private _signMethodType?: \"signTypedData\" | \"signMessage\" | \"signer\";\n\n constructor(options: K) {\n this.options = options;\n }\n\n /**\n * Sets the signer for the enclave.\n *\n * @param signer - The signer to set, is later used for MPC if allowed.\n */\n setSigner(signer: {\n signTypedData?: (domain: string, types: string[], value: string) => Promise<string>;\n // oxlint-disable-next-line typescript/no-explicit-any -- TODO: Change this when we know how to MPC & other chains\n signMessage?: (message: string) => Promise<any>;\n // oxlint-disable-next-line typescript/no-explicit-any -- TODO: Change this when we know how to MPC & other chains\n signer?: (message: string) => Promise<any>;\n }): void {\n if (signer.signTypedData) {\n // EVM wallet\n this._signMethod = signer.signTypedData.bind(signer);\n this._signMethodType = \"signTypedData\";\n } else if (signer.signMessage) {\n // XRPL wallet\n this._signMethod = signer.signMessage.bind(signer);\n this._signMethodType = \"signMessage\";\n } else if (signer.signer) {\n // Stellar wallet\n this._signMethod = signer.signer.bind(signer);\n this._signMethodType = \"signer\";\n } else {\n if ([\"signMessage\", \"signer\"].some((key) => key in signer)) {\n this._signMethod = signer.signMessage\n ? // @ts-expect-error - signMessage for xrpl and near, signer for stellar\n signer.signMessage.bind(signer)\n : // @ts-expect-error - signMessage for xrpl and near, signer for stellar\n signer.signer?.bind(signer);\n } else {\n throw new Error(\"No sign method found in passed signer\");\n }\n }\n }\n\n // oxlint-disable-next-line typescript/no-explicit-any -- TODO: Change this when we know how to MPC & other chains\n async signTypedData(domain: any, types: any, value: any): Promise<string> {\n if (!this._signMethod || !this._signMethodType) {\n throw new Error(\"Signer is not set\");\n }\n\n let signature: string;\n\n // Handle different signing methods based on wallet type\n if (this._signMethodType === \"signTypedData\") {\n // EVM wallets: use all 3 arguments\n signature =\n await // oxlint-disable-next-line typescript/no-explicit-any -- TODO: Change this when we know how to MPC & other chains\n (this._signMethod as (domain: any, types: any, value: any) => Promise<string>)(\n domain,\n types,\n value,\n );\n } else if (this._signMethodType === \"signMessage\" || this._signMethodType === \"signer\") {\n // XRPL/NEAR/Stellar/FaceSign wallets: use only the value as message\n const messageString = JSON.stringify(value);\n // oxlint-disable-next-line typescript/no-explicit-any -- TODO: Change this when we know how to MPC & other chains\n const response = await (this._signMethod as (message: any) => Promise<any>)(messageString);\n\n // Extract signature from response object\n if (typeof response === \"string\") {\n signature = response;\n } else if (response?.result?.signedMessage) {\n signature = response.result.signedMessage;\n } else if (response?.signedMessage) {\n signature = response.signedMessage;\n } else if (response instanceof Uint8Array && response.length === 64) {\n // ed25519 signature size\n return hexEncode(response);\n } else {\n throw new Error(\n `Unexpected response format from ${this._signMethodType}: ${JSON.stringify(response)}`,\n );\n }\n } else {\n throw new Error(`Unknown sign method type: ${this._signMethodType}`);\n }\n\n return signature;\n }\n\n /**\n * Helper method to get the user ID.\n *\n * @returns The user ID.\n */\n get userId(): string {\n if (!this.options.userId) {\n throw new Error(\"User ID is not present\");\n }\n return this.options.userId;\n }\n\n /**\n * Resets the enclave (storage etc.)\n */\n async reset(): Promise<void> {\n // Implement this if needed in child classes\n }\n\n /**\n * Reconfigures the enclave (theme etc).\n *\n * @param options - The options to reconfigure.\n */\n async reconfigure(options: Partial<K> = {}): Promise<void> {\n Object.assign(this.options, options);\n }\n\n /**\n * Loads the enclave (create iframe, open connection, etc.)\n */\n async load(): Promise<void> {\n await this.reconfigure();\n }\n\n /**\n * Encrypts a message to a receiver.\n * This method also checks if the user is authorized to use the keys.\n *\n * @param _message - The message to encrypt.\n * @param _receiverPublicKey - The public key of the receiver.\n *\n * @returns The encrypted message.\n */\n async encrypt(\n _message: Uint8Array,\n _receiverPublicKey: Uint8Array,\n ): Promise<{ content: Uint8Array; encryptorPublicKey: Uint8Array }> {\n throw new Error(\"Method 'encrypt' has to be implemented in the subclass.\");\n }\n\n /**\n * Decrypts a message from a sender.\n * This method also checks if the user is authorized to use the keys.\n *\n * @param _message - The message to decrypt.\n * @param _senderPublicKey - The public key of the sender.\n *\n * @returns The decrypted message.\n */\n async decrypt(\n _message: Uint8Array,\n _senderPublicKey: Uint8Array,\n ): Promise<Uint8Array<ArrayBufferLike>> {\n throw new Error(\"Method 'decrypt' has to be implemented in the subclass.\");\n }\n\n /**\n * This method is used to confirm the user action.\n *\n * @param _message - The message to confirm.\n *\n * @returns `true` if the user action is confirmed, `false` otherwise.\n */\n async confirm(_message: string): Promise<boolean> {\n throw new Error(\"Method 'confirm' has to be implemented in the subclass.\");\n }\n\n /**\n * This method is used to backup the password context.\n */\n async backupUserEncryptionProfile(): Promise<void> {\n throw new Error(\"Method 'backupUserEncryptionProfile' has to be implemented in the subclass.\");\n }\n\n /**\n * Gets the public encryption profile.\n *\n * @returns The public encryption profile.\n */\n async ensureUserEncryptionProfile(): Promise<PublicEncryptionProfile> {\n throw new Error(\"Method 'ensureUserEncryptionProfile' has to be implemented in the subclass.\");\n }\n\n /**\n * This method authorizes the origin in case of enclave\n * to use the keys, without user providing the password or MPC again.\n *\n * @returns `true` if the user action is authorized, `false` otherwise.\n */\n async guardKeys(): Promise<boolean> {\n return true;\n }\n\n /**\n * Filters the credentials based on the private field filters.\n *\n * @param credentials - The credentials to filter.\n * @param privateFieldFilters - The private field filters.\n *\n * @returns The filtered credentials without the content.\n */\n async filterCredentials(\n credentials: idOSCredential[],\n privateFieldFilters: { pick: Record<string, unknown[]>; omit: Record<string, unknown[]> },\n ): Promise<idOSCredential[]> {\n if (\n Object.keys(privateFieldFilters.pick).length === 0 &&\n Object.keys(privateFieldFilters.omit).length === 0\n ) {\n // No filtering needed\n return credentials.map((credential) => ({\n ...credential,\n content: \"\", // Content should never leave the enclave!!!\n }));\n }\n\n // We need to be sure first that we have the encryption profile\n // otherwise we can end up with a lot of signatures for each credential\n await this.ensureUserEncryptionProfile();\n\n const decrypted = await Promise.all(\n credentials.map(async (credential: idOSCredential) => {\n if (!credential.content) {\n throw new Error(`Credential ${credential.id} has no inline content`);\n }\n\n const content = await this.decrypt(\n base64Decode(credential.content),\n base64Decode(credential.encryptor_public_key),\n );\n\n let json: Record<string, unknown>;\n\n try {\n json = fromBytesToJson(content);\n } catch (_e) {\n throw new Error(`Credential ${credential.id} decrypted contents are not valid JSON`);\n }\n\n return {\n ...credential,\n content: json,\n };\n }),\n );\n\n return decrypted\n .filter(({ content }) =>\n recordFilter(\n content as Record<string, unknown>,\n privateFieldFilters.pick,\n privateFieldFilters.omit,\n ),\n )\n .map((credential) => ({\n ...credential,\n content: \"\", // Content should never leave the enclave!!!\n }));\n }\n\n async addAddressMessageToSign(\n _address: string,\n _publicKey: string | undefined,\n _addressToAddType: string,\n ): Promise<AddAddressMessageToSign> {\n throw new Error(\"Method 'addAddressMessageToSign' has to be implemented in the subclass.\");\n }\n\n async removeAddressMessageToSign(\n _address: string,\n _publicKey: string | undefined,\n _addressToRemoveType: string,\n ): Promise<RemoveAddressMessageToSign> {\n throw new Error(\"Method 'removeAddressMessageToSign' has to be implemented in the subclass.\");\n }\n\n async addAddressToMpcSecret(\n _userId: string,\n _message: AddAddressSignatureMessage,\n _signature: string,\n ): Promise<string> {\n throw new Error(\"Method 'addAddressToMpcSecret' has to be implemented in the subclass.\");\n }\n\n async removeAddressFromMpcSecret(\n _userId: string,\n _message: RemoveAddressSignatureMessage,\n _signature: string,\n ): Promise<string> {\n throw new Error(\"Method 'removeAddressFromMpcSecret' has to be implemented in the subclass.\");\n }\n}\n","export const STORAGE_KEYS = {\n DEPRECATED___ENCRYPTION_PRIVATE_KEY: \"encryption-private-key\",\n DEPRECATED___ENCRYPTION_SECRET_KEY: \"encryption-secret-key\",\n OBFUSCATED_BASE64_ENCRYPTION_SECRET_KEY: \"obfuscated-base64-encryption-secret-key\",\n ENCRYPTION_PUBLIC_KEY: \"encryption-public-key\",\n DEPRECATED___PASSWORD: \"password\",\n OBFUSCATED_PASSWORD: \"obfuscated-password\",\n USER_ID: \"user-id\",\n ENCRYPTION_PASSWORD_STORE: \"encryption-password-store\",\n};\n"],"mappings":"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"}
package/dist/local.d.mts CHANGED
@@ -1,11 +1,10 @@
1
- import { g as RemoveAddressMessageToSign, i as AddAddressSignatureMessage, n as AddAddressMessageToSign, v as RemoveAddressSignatureMessage } from "./types-DKsOwtWL.mjs";
2
- import { a as PasswordContext, i as MPCPasswordContext, n as EnclaveOptions, o as PrivateEncryptionProfile, s as PublicEncryptionProfile, t as BaseProvider } from "./base-0xSNl4rW.mjs";
3
- import { t as Client } from "./client-Bu0aO5sT.mjs";
1
+ import { g as RemoveAddressMessageToSign, i as AddAddressSignatureMessage, n as AddAddressMessageToSign, v as RemoveAddressSignatureMessage } from "./types-Ck9Ec1Pa.mjs";
2
+ import { a as PasswordContext, i as MPCPasswordContext, n as EnclaveOptions, o as PrivateEncryptionProfile, s as PublicEncryptionProfile, t as BaseProvider } from "./base-CjIdohef.mjs";
3
+ import { t as Client } from "./client-Ci4XBJXn.mjs";
4
4
  import { Store } from "@idos-network/utils/store";
5
5
  import { EncryptionPasswordStore } from "@idos-network/kwil-infra/actions";
6
-
7
6
  //#region src/local.d.ts
8
- interface LocalEnclaveOptions extends EnclaveOptions {
7
+ export interface LocalEnclaveOptions extends EnclaveOptions {
9
8
  store?: Store;
10
9
  allowedEncryptionStores?: EncryptionPasswordStore[];
11
10
  mpcConfiguration?: {
@@ -16,7 +15,7 @@ interface LocalEnclaveOptions extends EnclaveOptions {
16
15
  numToReconstruct: number;
17
16
  };
18
17
  }
19
- declare class LocalEnclave<K extends LocalEnclaveOptions = LocalEnclaveOptions> extends BaseProvider<K> {
18
+ export declare class LocalEnclave<K extends LocalEnclaveOptions = LocalEnclaveOptions> extends BaseProvider<K> {
20
19
  protected allowedEncryptionStores: EncryptionPasswordStore[];
21
20
  protected store: Store;
22
21
  protected storeBase64: Store;
@@ -30,57 +29,57 @@ declare class LocalEnclave<K extends LocalEnclaveOptions = LocalEnclaveOptions>
30
29
  /** @override parent method to reconfigure the enclave */
31
30
  reconfigure(options?: Partial<K>): Promise<void>;
32
31
  /**
33
- * Return a codec that encrypts/decrypts data using a key derived from the provider's user ID.
34
- *
35
- * This ensures that data is minimally obfuscated to avoid low-sophistication attacks.
36
- */
32
+ * Return a codec that encrypts/decrypts data using a key derived from the provider's user ID.
33
+ *
34
+ * This ensures that data is minimally obfuscated to avoid low-sophistication attacks.
35
+ */
37
36
  private userIdObfuscationCodec;
38
37
  /** @see parent method extended with loading the profile from the store */
39
38
  load(): Promise<void>;
40
39
  /**
41
- * Encrypts a message to a receiver.
42
- * This method also checks if the user is authorized to use the keys.
43
- *
44
- * @param message - The message to encrypt.
45
- * @param receiverPublicKey - The public key of the receiver.
46
- *
47
- * @returns The encrypted message.
48
- */
40
+ * Encrypts a message to a receiver.
41
+ * This method also checks if the user is authorized to use the keys.
42
+ *
43
+ * @param message - The message to encrypt.
44
+ * @param receiverPublicKey - The public key of the receiver.
45
+ *
46
+ * @returns The encrypted message.
47
+ */
49
48
  encrypt(message: Uint8Array, receiverPublicKey: Uint8Array): Promise<{
50
49
  content: Uint8Array;
51
50
  encryptorPublicKey: Uint8Array;
52
51
  }>;
53
52
  /**
54
- * Decrypts a message from a sender.
55
- * This method also checks if the user is authorized to use the keys.
56
- *
57
- * @param message - The message to decrypt.
58
- * @param senderPublicKey - The public key of the sender.
59
- *
60
- * @returns The decrypted message.
61
- */
53
+ * Decrypts a message from a sender.
54
+ * This method also checks if the user is authorized to use the keys.
55
+ *
56
+ * @param message - The message to decrypt.
57
+ * @param senderPublicKey - The public key of the sender.
58
+ *
59
+ * @returns The decrypted message.
60
+ */
62
61
  decrypt(message: Uint8Array, senderPublicKey: Uint8Array): Promise<Uint8Array<ArrayBufferLike>>;
63
62
  /**
64
- * @see BaseProvider#getPrivateEncryptionProfile
65
- */
63
+ * @see BaseProvider#getPrivateEncryptionProfile
64
+ */
66
65
  getPrivateEncryptionProfile(skipGuard?: boolean): Promise<PrivateEncryptionProfile>;
67
66
  /** @see BaseProvider#ensureUserEncryptionProfile */
68
67
  ensureUserEncryptionProfile(): Promise<PublicEncryptionProfile>;
69
68
  /**
70
- * This method needs to check `options` and should derive the password context from it.
71
- *
72
- * @returns The password context.
73
- */
69
+ * This method needs to check `options` and should derive the password context from it.
70
+ *
71
+ * @returns The password context.
72
+ */
74
73
  getPasswordContext(): Promise<PasswordContext | MPCPasswordContext>;
75
74
  /**
76
- * Creates and store encryption profile from a password.
77
- *
78
- * @param password - The password to use.
79
- * @param userId - The user id to use.
80
- * @param encryptionPasswordStore - The encryption password store to use.
81
- *
82
- * @returns The encryption profile.
83
- */
75
+ * Creates and store encryption profile from a password.
76
+ *
77
+ * @param password - The password to use.
78
+ * @param userId - The user id to use.
79
+ * @param encryptionPasswordStore - The encryption password store to use.
80
+ *
81
+ * @returns The encryption profile.
82
+ */
84
83
  createEncryptionProfileFromPassword(password: string, userId: string, encryptionPasswordStore: EncryptionPasswordStore): Promise<PrivateEncryptionProfile>;
85
84
  protected ensureMPCPassword(): Promise<string>;
86
85
  private get mpcClient();
@@ -92,5 +91,4 @@ declare class LocalEnclave<K extends LocalEnclaveOptions = LocalEnclaveOptions>
92
91
  removeAddressFromMpcSecret(userId: string, message: RemoveAddressSignatureMessage, signature: string): Promise<string>;
93
92
  }
94
93
  //#endregion
95
- export { LocalEnclave, LocalEnclaveOptions };
96
94
  //# sourceMappingURL=local.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"local.d.mts","names":[],"sources":["../src/local.ts"],"mappings":";;;;;;;UAoCiB,mBAAA,SAA4B,cAAA;EAC3C,KAAA,GAAQ,KAAA;EACR,uBAAA,GAA0B,uBAAA;EAC1B,gBAAA;IACE,OAAA;IACA,eAAA;IACA,YAAA;IACA,QAAA;IACA,gBAAA;EAAA;AAAA;AAAA,cAIS,YAAA,WACD,mBAAA,GAAsB,mBAAA,UACxB,YAAA,CAAa,CAAA;EAAA,UACX,uBAAA,EAAyB,uBAAA;EAAA,UAGzB,KAAA,EAAO,KAAA;EAAA,UACP,WAAA,EAAa,KAAA;EAAA,UACb,eAAA,EAAiB,KAAA;EAAA,UACjB,qBAAA,EAAuB,KAAA;EAAA,UAGvB,iBAAA,GAAoB,MAAA;EAAA,UAKpB,uBAAA,GAA0B,wBAAA;EAEpC,WAAA,CAAY,OAAA,EAAS,CAAA;;EA4BrB,KAAA,CAAA,GAAe,OAAA;EA/CjB;EAsDE,WAAA,CAAkB,OAAA,GAAS,OAAA,CAAQ,CAAA,IAAU,OAAA;;;;;;UAiBrC,sBAAA;;EAoDR,IAAA,CAAA,GAAc,OAAA;;;;;;;;;;EAoEd,OAAA,CACE,OAAA,EAAS,UAAA,EACT,iBAAA,EAAmB,UAAA,GAClB,OAAA;IAAU,OAAA,EAAS,UAAA;IAAY,kBAAA,EAAoB,UAAA;EAAA;;;;;;;;;;EActD,OAAA,CACE,OAAA,EAAS,UAAA,EACT,eAAA,EAAiB,UAAA,GAChB,OAAA,CAAQ,UAAA,CAAW,eAAA;;;;EAQtB,2BAAA,CAAkC,SAAA,aAAoB,OAAA,CAAQ,wBAAA;;EAiD9D,2BAAA,CAAA,GAAqC,OAAA,CAAQ,uBAAA;;;;;;EAe7C,kBAAA,CAAA,GAA4B,OAAA,CAAQ,eAAA,GAAkB,kBAAA;;;;;;;;;;EAatD,mCAAA,CACE,QAAA,UACA,MAAA,UACA,uBAAA,EAAyB,uBAAA,GACxB,OAAA,CAAQ,wBAAA;EAAA,UA0BK,iBAAA,CAAA,GAAqB,OAAA;EAAA,YAqBzB,SAAA,CAAA;EAAA,QAOE,cAAA;EAAA,QA+BA,YAAA;EAsBd,uBAAA,CACE,OAAA,UACA,SAAA,sBACA,gBAAA,WACC,OAAA,CAAQ,uBAAA;EAQX,0BAAA,CACE,OAAA,UACA,SAAA,sBACA,mBAAA,WACC,OAAA,CAAQ,0BAAA;EAQX,qBAAA,CACE,MAAA,UACA,OAAA,EAAS,0BAAA,EACT,SAAA,WACC,OAAA;EAIH,0BAAA,CACE,MAAA,UACA,OAAA,EAAS,6BAAA,EACT,SAAA,WACC,OAAA;AAAA"}
1
+ {"version":3,"file":"local.d.mts","names":[],"sources":["../src/local.ts"],"mappings":";;;;;;iBAoCiB,4BAA4B;EAC3C,QAAQ;EACR,0BAA0B;EAC1B;IACE;IACA;IACA;IACA;IACA;;;qBAIS,aACX,UAAU,sBAAsB,6BACxB,aAAa;YACX,yBAAyB;YAGzB,OAAO;YACP,aAAa;YACb,iBAAiB;YACjB,uBAAuB;YAGvB,oBAAoB;YAKpB,0BAA0B;EAEpC,YAAY,SAAS;;EA4BrB,SAAe;;EAOf,YAAkB,UAAS,QAAQ,KAAU;;;;;;UAiBrC;;EAoDR,QAAc;;;;;;;;;;EAoEd,QACE,SAAS,YACT,mBAAmB,aAClB;IAAU,SAAS;IAAY,oBAAoB;;;;;;;;;;;EActD,QACE,SAAS,YACT,iBAAiB,aAChB,QAAQ,WAAW;;;;EAQtB,4BAAkC,sBAAoB,QAAQ;;EAkE9D,+BAAqC,QAAQ;;;;;;EAe7C,sBAA4B,QAAQ,kBAAkB;;;;;;;;;;EAatD,oCACE,kBACA,gBACA,yBAAyB,0BACxB,QAAQ;YAiCK,qBAAqB;cAqBzB;UAOE;UA+BA;EAsBd,wBACE,iBACA,+BACA,2BACC,QAAQ;EAQX,2BACE,iBACA,+BACA,8BACC,QAAQ;EAQX,sBACE,gBACA,SAAS,4BACT,oBACC;EAIH,2BACE,gBACA,SAAS,+BACT,oBACC"}
package/dist/local.mjs CHANGED
@@ -1,253 +1,2 @@
1
- import { n as BaseProvider, t as STORAGE_KEYS } from "./keys-RuC1M-_K.mjs";
2
- import { t as Client } from "./client-rcvBXslm.mjs";
3
- import { base64Codec, base64Encode, hexDecode, hexEncode, utf8Decode, utf8Encode } from "@idos-network/utils/codecs";
4
- import { generatePassword } from "@idos-network/utils/cryptography";
5
- import { decrypt, encrypt, keyDerivation } from "@idos-network/utils/encryption";
6
- import { LocalStorageStore } from "@idos-network/utils/store";
7
- import { syncScrypt } from "scrypt-js";
8
- import nacl from "tweetnacl";
9
- //#region src/local.ts
10
- var LocalEnclave = class extends BaseProvider {
11
- allowedEncryptionStores;
12
- store;
13
- storeBase64;
14
- storeObfuscated;
15
- storeObfuscatedBase64;
16
- mpcClientInstance;
17
- storedEncryptionProfile;
18
- constructor(options) {
19
- super(options);
20
- this.allowedEncryptionStores = options.allowedEncryptionStores ?? ["user"];
21
- this.store = options.store ?? new LocalStorageStore();
22
- this.storeObfuscated = this.store.pipeCodec(this.userIdObfuscationCodec());
23
- this.storeBase64 = this.store.pipeCodec(base64Codec);
24
- this.storeObfuscatedBase64 = this.store.pipeCodec(this.userIdObfuscationCodec()).pipeCodec(base64Codec);
25
- if (options.mpcConfiguration) this.mpcClientInstance = new Client(options.mpcConfiguration.nodeUrl, options.mpcConfiguration.contractAddress, options.mpcConfiguration.numMalicious, options.mpcConfiguration.numNodes, options.mpcConfiguration.numToReconstruct, options.walletType ?? "EVM", options.walletAddress ?? "", options.walletPublicKey);
26
- }
27
- /** @override parent method to reset the enclave */
28
- async reset() {
29
- await super.reset();
30
- this.storedEncryptionProfile = void 0;
31
- this.store.reset();
32
- }
33
- /** @override parent method to reconfigure the enclave */
34
- async reconfigure(options = {}) {
35
- await super.reconfigure(options);
36
- if (this.mpcClientInstance && options.walletType && options.walletAddress) this.mpcClientInstance.reconfigure(options.walletType, options.walletAddress ?? "", options.walletPublicKey);
37
- }
38
- /**
39
- * Return a codec that encrypts/decrypts data using a key derived from the provider's user ID.
40
- *
41
- * This ensures that data is minimally obfuscated to avoid low-sophistication attacks.
42
- */
43
- userIdObfuscationCodec() {
44
- const self = this;
45
- const toKey = (userId, salt) => syncScrypt(utf8Encode(userId), salt, 16384, 8, 1, nacl.secretbox.keyLength);
46
- return {
47
- encode(data) {
48
- if (!self.options.userId) throw new Error("User ID required for encryption");
49
- const dataBytes = utf8Encode(data);
50
- const nonce = nacl.randomBytes(nacl.secretbox.nonceLength);
51
- const salt = nacl.randomBytes(16);
52
- const key = toKey(self.options.userId, salt);
53
- const payload = nacl.secretbox(dataBytes, nonce, key);
54
- const combined = new Uint8Array(salt.length + nonce.length + payload.length);
55
- combined.set(salt, 0);
56
- combined.set(nonce, salt.length);
57
- combined.set(payload, salt.length + nonce.length);
58
- return `0x${hexEncode(combined)}`;
59
- },
60
- decode(payload) {
61
- if (!self.options.userId) throw new Error("User ID required for decryption");
62
- if (payload.slice(0, 2) !== "0x") throw new Error(`missing 0x prefix: ${payload}`);
63
- const combined = hexDecode(payload.slice(2));
64
- const salt = combined.slice(0, 16);
65
- const nonce = combined.slice(16, 16 + nacl.secretbox.nonceLength);
66
- const ciphertext = combined.slice(16 + nacl.secretbox.nonceLength);
67
- const key = toKey(self.options.userId, salt);
68
- const result = nacl.secretbox.open(ciphertext, nonce, key);
69
- if (!result) throw new Error("Failed to decrypt data");
70
- return utf8Decode(result);
71
- }
72
- };
73
- }
74
- /** @see parent method extended with loading the profile from the store */
75
- async load() {
76
- await super.load();
77
- const userId = await this.store.get(STORAGE_KEYS.USER_ID);
78
- if (userId) this.options.userId = userId;
79
- let password = await this.storeObfuscated.get(STORAGE_KEYS.OBFUSCATED_PASSWORD);
80
- if (!password) {
81
- password = await this.store.get(STORAGE_KEYS.DEPRECATED___PASSWORD);
82
- if (!password) return;
83
- await this.storeObfuscated.set(STORAGE_KEYS.OBFUSCATED_PASSWORD, password);
84
- }
85
- await this.store.delete(STORAGE_KEYS.DEPRECATED___PASSWORD);
86
- let encryptionSecretKey = await this.storeObfuscatedBase64.get(STORAGE_KEYS.OBFUSCATED_BASE64_ENCRYPTION_SECRET_KEY);
87
- if (!encryptionSecretKey) {
88
- encryptionSecretKey = await this.storeBase64.get(STORAGE_KEYS.DEPRECATED___ENCRYPTION_SECRET_KEY);
89
- if (!encryptionSecretKey) return;
90
- await this.storeObfuscatedBase64.set(STORAGE_KEYS.OBFUSCATED_BASE64_ENCRYPTION_SECRET_KEY, encryptionSecretKey);
91
- }
92
- await this.store.delete(STORAGE_KEYS.DEPRECATED___ENCRYPTION_SECRET_KEY);
93
- await this.store.delete(STORAGE_KEYS.DEPRECATED___ENCRYPTION_PRIVATE_KEY);
94
- if (!password || !userId || !encryptionSecretKey) return;
95
- let encryptionPasswordStore = await this.store.get(STORAGE_KEYS.ENCRYPTION_PASSWORD_STORE);
96
- if (!encryptionPasswordStore || encryptionPasswordStore === "password") {
97
- encryptionPasswordStore = "user";
98
- await this.store.set(STORAGE_KEYS.ENCRYPTION_PASSWORD_STORE, encryptionPasswordStore);
99
- }
100
- this.storedEncryptionProfile = {
101
- userId,
102
- password,
103
- keyPair: nacl.box.keyPair.fromSecretKey(encryptionSecretKey),
104
- encryptionPasswordStore
105
- };
106
- }
107
- /**
108
- * Encrypts a message to a receiver.
109
- * This method also checks if the user is authorized to use the keys.
110
- *
111
- * @param message - The message to encrypt.
112
- * @param receiverPublicKey - The public key of the receiver.
113
- *
114
- * @returns The encrypted message.
115
- */
116
- async encrypt(message, receiverPublicKey) {
117
- const { keyPair } = await this.getPrivateEncryptionProfile();
118
- return encrypt(message, keyPair.publicKey, receiverPublicKey);
119
- }
120
- /**
121
- * Decrypts a message from a sender.
122
- * This method also checks if the user is authorized to use the keys.
123
- *
124
- * @param message - The message to decrypt.
125
- * @param senderPublicKey - The public key of the sender.
126
- *
127
- * @returns The decrypted message.
128
- */
129
- async decrypt(message, senderPublicKey) {
130
- const { keyPair } = await this.getPrivateEncryptionProfile();
131
- return decrypt(message, keyPair, senderPublicKey);
132
- }
133
- /**
134
- * @see BaseProvider#getPrivateEncryptionProfile
135
- */
136
- async getPrivateEncryptionProfile(skipGuard = false) {
137
- if (this.storedEncryptionProfile) {
138
- let canBeUsed = this.storedEncryptionProfile.userId === this.userId;
139
- if (canBeUsed && !skipGuard) canBeUsed = await this.guardKeys();
140
- if (canBeUsed) return this.storedEncryptionProfile;
141
- await this.reset();
142
- }
143
- let password;
144
- let encryptionPasswordStore;
145
- const context = await this.getPasswordContext();
146
- if (context.encryptionPasswordStore === "user") {
147
- await this.store.setRememberDuration(context.duration);
148
- password = context.password;
149
- encryptionPasswordStore = context.encryptionPasswordStore;
150
- }
151
- if (context.encryptionPasswordStore === "mpc") {
152
- await this.store.setRememberDuration(void 0);
153
- password = await this.ensureMPCPassword();
154
- encryptionPasswordStore = "mpc";
155
- }
156
- if (!password || !encryptionPasswordStore) throw new Error("Password or encryption password store is not found");
157
- return this.createEncryptionProfileFromPassword(password, this.userId, encryptionPasswordStore);
158
- }
159
- /** @see BaseProvider#ensureUserEncryptionProfile */
160
- async ensureUserEncryptionProfile() {
161
- const { keyPair, encryptionPasswordStore, userId } = await this.getPrivateEncryptionProfile();
162
- return {
163
- userId,
164
- userEncryptionPublicKey: base64Encode(keyPair.publicKey),
165
- encryptionPasswordStore
166
- };
167
- }
168
- /**
169
- * This method needs to check `options` and should derive the password context from it.
170
- *
171
- * @returns The password context.
172
- */
173
- async getPasswordContext() {
174
- throw new Error("Method 'getPasswordContext' has to be implemented in the subclass.");
175
- }
176
- /**
177
- * Creates and store encryption profile from a password.
178
- *
179
- * @param password - The password to use.
180
- * @param userId - The user id to use.
181
- * @param encryptionPasswordStore - The encryption password store to use.
182
- *
183
- * @returns The encryption profile.
184
- */
185
- async createEncryptionProfileFromPassword(password, userId, encryptionPasswordStore) {
186
- const secretKey = await keyDerivation(password, userId);
187
- const keyPair = nacl.box.keyPair.fromSecretKey(secretKey);
188
- await this.store.set(STORAGE_KEYS.USER_ID, userId);
189
- await this.storeObfuscated.set(STORAGE_KEYS.OBFUSCATED_PASSWORD, password);
190
- await this.store.delete(STORAGE_KEYS.DEPRECATED___PASSWORD);
191
- await this.store.set(STORAGE_KEYS.ENCRYPTION_PASSWORD_STORE, encryptionPasswordStore);
192
- await this.storeObfuscatedBase64.set(STORAGE_KEYS.OBFUSCATED_BASE64_ENCRYPTION_SECRET_KEY, keyPair.secretKey);
193
- await this.store.delete(STORAGE_KEYS.DEPRECATED___ENCRYPTION_SECRET_KEY);
194
- await this.storeBase64.set(STORAGE_KEYS.ENCRYPTION_PUBLIC_KEY, keyPair.publicKey);
195
- this.storedEncryptionProfile = {
196
- userId,
197
- password,
198
- keyPair,
199
- encryptionPasswordStore
200
- };
201
- return this.storedEncryptionProfile;
202
- }
203
- async ensureMPCPassword() {
204
- if (this.options?.mode !== "new") {
205
- const { status: downloadStatus, secret: downloadedPassword } = await this.downloadSecret();
206
- if (downloadStatus === "ok" && downloadedPassword) return utf8Decode(downloadedPassword);
207
- throw Error("A secret might be stored at MPC ZK nodes, but can't be obtained");
208
- }
209
- const password = generatePassword();
210
- const { status: uploadStatus } = await this.uploadSecret(password);
211
- if (uploadStatus !== "success") throw Error(`A secret upload failed with status: ${uploadStatus}`);
212
- return password;
213
- }
214
- get mpcClient() {
215
- if (!this.mpcClientInstance) throw new Error("MPC client is not initialized");
216
- return this.mpcClientInstance;
217
- }
218
- async downloadSecret() {
219
- if (!this.options.walletAddress) throw new Error("walletAddress is not found");
220
- const ephemeralKeyPair = nacl.box.keyPair();
221
- const downloadRequest = this.mpcClient.downloadRequest(ephemeralKeyPair.publicKey);
222
- const messageToSign = this.mpcClient.downloadMessageToSign(downloadRequest);
223
- const signedMessage = await this.signTypedData(messageToSign.domain, messageToSign.types, messageToSign.value);
224
- return this.mpcClient.downloadSecret(this.userId, downloadRequest, signedMessage, ephemeralKeyPair.secretKey);
225
- }
226
- async uploadSecret(secret) {
227
- if (!this.options.walletAddress) {
228
- console.error("signerAddress is not found");
229
- return { status: "no-signer-address" };
230
- }
231
- const blindedShares = this.mpcClient.getBlindedShares(Buffer.from(secret, "utf8"));
232
- const uploadRequest = this.mpcClient.uploadRequest(blindedShares);
233
- const messageToSign = this.mpcClient.uploadMessageToSign(uploadRequest);
234
- const signedMessage = await this.signTypedData(messageToSign.domain, messageToSign.types, messageToSign.value);
235
- return this.mpcClient.uploadSecret(this.userId, uploadRequest, signedMessage, blindedShares);
236
- }
237
- async addAddressMessageToSign(address, publicKey, addressToAddType) {
238
- return this.mpcClient.addAddressMessageToSign(address, publicKey, addressToAddType);
239
- }
240
- async removeAddressMessageToSign(address, publicKey, addressToRemoveType) {
241
- return this.mpcClient.removeAddressMessageToSign(address, publicKey, addressToRemoveType);
242
- }
243
- async addAddressToMpcSecret(userId, message, signature) {
244
- return this.mpcClient.addAddress(userId, message, signature);
245
- }
246
- async removeAddressFromMpcSecret(userId, message, signature) {
247
- return this.mpcClient.removeAddress(userId, message, signature);
248
- }
249
- };
250
- //#endregion
251
- export { LocalEnclave };
252
-
1
+ import{n as e,t}from"./keys-P2XLU3qP.mjs";import{t as n}from"./client-Dqb0xbdb.mjs";import{base64Codec as r,base64Encode as i,hexDecode as a,hexEncode as o,utf8Decode as s,utf8Encode as c}from"@idos-network/utils/codecs";import{generatePassword as l}from"@idos-network/utils/cryptography";import{decrypt as u,encrypt as d,keyDerivation as f}from"@idos-network/utils/encryption";import{LocalStorageStore as p}from"@idos-network/utils/store";import{syncScrypt as m}from"scrypt-js";import h from"tweetnacl";var g=class extends e{allowedEncryptionStores;store;storeBase64;storeObfuscated;storeObfuscatedBase64;mpcClientInstance;storedEncryptionProfile;constructor(e){super(e),this.allowedEncryptionStores=e.allowedEncryptionStores??[`user`],this.store=e.store??new p,this.storeObfuscated=this.store.pipeCodec(this.userIdObfuscationCodec()),this.storeBase64=this.store.pipeCodec(r),this.storeObfuscatedBase64=this.store.pipeCodec(this.userIdObfuscationCodec()).pipeCodec(r),e.mpcConfiguration&&(this.mpcClientInstance=new n(e.mpcConfiguration.nodeUrl,e.mpcConfiguration.contractAddress,e.mpcConfiguration.numMalicious,e.mpcConfiguration.numNodes,e.mpcConfiguration.numToReconstruct,e.walletType??`EVM`,e.walletAddress??``,e.walletPublicKey))}async reset(){await super.reset(),this.storedEncryptionProfile=void 0,await this.store.reset()}async reconfigure(e={}){await super.reconfigure(e),this.mpcClientInstance&&e.walletType&&e.walletAddress&&this.mpcClientInstance.reconfigure(e.walletType,e.walletAddress??``,e.walletPublicKey)}userIdObfuscationCodec(){let e=this,t=(e,t)=>m(c(e),t,16384,8,1,h.secretbox.keyLength);return{encode(n){if(!e.options.userId)throw Error(`User ID required for encryption`);let r=c(n),i=h.randomBytes(h.secretbox.nonceLength),a=h.randomBytes(16),s=t(e.options.userId,a),l=h.secretbox(r,i,s),u=new Uint8Array(a.length+i.length+l.length);return u.set(a,0),u.set(i,a.length),u.set(l,a.length+i.length),`0x${o(u)}`},decode(n){if(!e.options.userId)throw Error(`User ID required for decryption`);if(n.slice(0,2)!==`0x`)throw Error(`missing 0x prefix: ${n}`);let r=a(n.slice(2)),i=r.slice(0,16),o=r.slice(16,16+h.secretbox.nonceLength),c=r.slice(16+h.secretbox.nonceLength),l=t(e.options.userId,i),u=h.secretbox.open(c,o,l);if(!u)throw Error(`Failed to decrypt data`);return s(u)}}}async load(){await super.load();let e=await this.store.get(t.USER_ID);e&&(this.options.userId=e);let n=await this.storeObfuscated.get(t.OBFUSCATED_PASSWORD);if(!n){if(n=await this.store.get(t.DEPRECATED___PASSWORD),!n)return;await this.storeObfuscated.set(t.OBFUSCATED_PASSWORD,n)}await this.store.delete(t.DEPRECATED___PASSWORD);let r=await this.storeObfuscatedBase64.get(t.OBFUSCATED_BASE64_ENCRYPTION_SECRET_KEY);if(!r){if(r=await this.storeBase64.get(t.DEPRECATED___ENCRYPTION_SECRET_KEY),!r)return;await this.storeObfuscatedBase64.set(t.OBFUSCATED_BASE64_ENCRYPTION_SECRET_KEY,r)}if(await this.store.delete(t.DEPRECATED___ENCRYPTION_SECRET_KEY),await this.store.delete(t.DEPRECATED___ENCRYPTION_PRIVATE_KEY),!n||!e||!r)return;let i=await this.store.get(t.ENCRYPTION_PASSWORD_STORE);(!i||i===`password`)&&(i=`user`,await this.store.set(t.ENCRYPTION_PASSWORD_STORE,i)),this.storedEncryptionProfile={userId:e,password:n,keyPair:h.box.keyPair.fromSecretKey(r),encryptionPasswordStore:i}}async encrypt(e,t){let{keyPair:n}=await this.getPrivateEncryptionProfile();return d(e,n.publicKey,t)}async decrypt(e,t){let{keyPair:n}=await this.getPrivateEncryptionProfile();return u(e,n,t)}async getPrivateEncryptionProfile(e=!1){if(this.storedEncryptionProfile&&await this.store.hasRememberDurationElapsed()&&await this.reset(),this.storedEncryptionProfile?.userId===this.userId){if(!e&&!await this.guardKeys())throw Error(`Origin is not authorized to use the keys`);return this.storedEncryptionProfile}if(this.storedEncryptionProfile&&await this.reset(),this.options.encryptionPasswordStore===`mm`)throw Error(`MM encryption profiles require an externally supplied encryption private key`);let t,n,r=await this.getPasswordContext();if(r.encryptionPasswordStore===`user`&&(await this.store.setRememberDuration(r.duration),t=r.password,n=r.encryptionPasswordStore),r.encryptionPasswordStore===`mpc`&&(await this.store.setRememberDuration(void 0),t=await this.ensureMPCPassword(),n=`mpc`),!t||!n)throw Error(`Password or encryption password store is not found`);let i=await this.createEncryptionProfileFromPassword(t,this.userId,n);if(!e&&!await this.guardKeys())throw Error(`Origin is not authorized to use the keys`);return i}async ensureUserEncryptionProfile(){let{keyPair:e,encryptionPasswordStore:t,userId:n}=await this.getPrivateEncryptionProfile();return{userId:n,userEncryptionPublicKey:i(e.publicKey),encryptionPasswordStore:t}}async getPasswordContext(){throw Error(`Method 'getPasswordContext' has to be implemented in the subclass.`)}async createEncryptionProfileFromPassword(e,n,r){let a=await f(e,n),o=h.box.keyPair.fromSecretKey(a),s=this.options.expectedUserEncryptionPublicKey;if(s&&i(o.publicKey)!==s)throw Error(`Derived encryption public key does not match expectedUserEncryptionPublicKey`);return await this.store.set(t.USER_ID,n),await this.storeObfuscated.set(t.OBFUSCATED_PASSWORD,e),await this.store.delete(t.DEPRECATED___PASSWORD),await this.store.set(t.ENCRYPTION_PASSWORD_STORE,r),await this.storeObfuscatedBase64.set(t.OBFUSCATED_BASE64_ENCRYPTION_SECRET_KEY,o.secretKey),await this.store.delete(t.DEPRECATED___ENCRYPTION_SECRET_KEY),await this.storeBase64.set(t.ENCRYPTION_PUBLIC_KEY,o.publicKey),this.storedEncryptionProfile={userId:n,password:e,keyPair:o,encryptionPasswordStore:r},this.storedEncryptionProfile}async ensureMPCPassword(){if(this.options?.mode!==`new`){let{status:e,secret:t}=await this.downloadSecret();if(e===`ok`&&t)return s(t);throw Error(`A secret might be stored at MPC ZK nodes, but can't be obtained`)}let e=l(),{status:t}=await this.uploadSecret(e);if(t!==`success`)throw Error(`A secret upload failed with status: ${t}`);return e}get mpcClient(){if(!this.mpcClientInstance)throw Error(`MPC client is not initialized`);return this.mpcClientInstance}async downloadSecret(){if(!this.options.walletAddress)throw Error(`walletAddress is not found`);let e=h.box.keyPair(),t=this.mpcClient.downloadRequest(e.publicKey),n=this.mpcClient.downloadMessageToSign(t),r=await this.signTypedData(n.domain,n.types,n.value);return this.mpcClient.downloadSecret(this.userId,t,r,e.secretKey)}async uploadSecret(e){if(!this.options.walletAddress)return console.error(`signerAddress is not found`),{status:`no-signer-address`};let t=this.mpcClient.getBlindedShares(Buffer.from(e,`utf8`)),n=this.mpcClient.uploadRequest(t),r=this.mpcClient.uploadMessageToSign(n),i=await this.signTypedData(r.domain,r.types,r.value);return this.mpcClient.uploadSecret(this.userId,n,i,t)}async addAddressMessageToSign(e,t,n){return this.mpcClient.addAddressMessageToSign(e,t,n)}async removeAddressMessageToSign(e,t,n){return this.mpcClient.removeAddressMessageToSign(e,t,n)}async addAddressToMpcSecret(e,t,n){return this.mpcClient.addAddress(e,t,n)}async removeAddressFromMpcSecret(e,t,n){return this.mpcClient.removeAddress(e,t,n)}};export{g as LocalEnclave};
253
2
  //# sourceMappingURL=local.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"local.mjs","names":["MPCClient"],"sources":["../src/local.ts"],"sourcesContent":["import type { EncryptionPasswordStore } from \"@idos-network/kwil-infra/actions\";\n\nimport {\n base64Codec,\n base64Encode,\n hexDecode,\n hexEncode,\n utf8Decode,\n utf8Encode,\n} from \"@idos-network/utils/codecs\";\nimport { generatePassword } from \"@idos-network/utils/cryptography\";\nimport { decrypt, encrypt, keyDerivation } from \"@idos-network/utils/encryption\";\nimport { LocalStorageStore, type PipeCodecArgs, type Store } from \"@idos-network/utils/store\";\nimport { syncScrypt } from \"scrypt-js\";\nimport nacl from \"tweetnacl\";\n\nimport type {\n AddAddressMessageToSign,\n AddAddressSignatureMessage,\n DownloadMessageToSign,\n RemoveAddressMessageToSign,\n RemoveAddressSignatureMessage,\n UploadMessageToSign,\n} from \"./mpc/types\";\nimport type {\n EnclaveOptions,\n MPCPasswordContext,\n PasswordContext,\n PrivateEncryptionProfile,\n PublicEncryptionProfile,\n} from \"./types\";\n\nimport { BaseProvider } from \"./base\";\nimport { STORAGE_KEYS } from \"./keys\";\nimport { Client as MPCClient } from \"./mpc/client\";\n\nexport interface LocalEnclaveOptions extends EnclaveOptions {\n store?: Store;\n allowedEncryptionStores?: EncryptionPasswordStore[];\n mpcConfiguration?: {\n nodeUrl: string;\n contractAddress: string;\n numMalicious: number;\n numNodes: number;\n numToReconstruct: number;\n };\n}\n\nexport class LocalEnclave<\n K extends LocalEnclaveOptions = LocalEnclaveOptions,\n> extends BaseProvider<K> {\n protected allowedEncryptionStores: EncryptionPasswordStore[];\n\n // Store for data\n protected store: Store;\n protected storeBase64: Store;\n protected storeObfuscated: Store;\n protected storeObfuscatedBase64: Store;\n\n // In case of MPC usage\n protected mpcClientInstance?: MPCClient;\n\n // Stored key pair and user id for that key pair\n // those are most likely loaded from the store\n // during the load() method.\n protected storedEncryptionProfile?: PrivateEncryptionProfile;\n\n constructor(options: K) {\n super(options);\n\n // By default, we only allow password auth method\n this.allowedEncryptionStores = options.allowedEncryptionStores ?? [\"user\"];\n this.store = options.store ?? new LocalStorageStore();\n this.storeObfuscated = this.store.pipeCodec(this.userIdObfuscationCodec());\n this.storeBase64 = this.store.pipeCodec(base64Codec);\n this.storeObfuscatedBase64 = this.store\n .pipeCodec(this.userIdObfuscationCodec())\n .pipeCodec(base64Codec);\n\n if (options.mpcConfiguration) {\n this.mpcClientInstance = new MPCClient(\n options.mpcConfiguration.nodeUrl,\n options.mpcConfiguration.contractAddress,\n options.mpcConfiguration.numMalicious,\n options.mpcConfiguration.numNodes,\n options.mpcConfiguration.numToReconstruct,\n // TODO: This is weird, we should not be forcing this\n options.walletType ?? \"EVM\",\n options.walletAddress ?? \"\",\n options.walletPublicKey,\n );\n }\n }\n\n /** @override parent method to reset the enclave */\n async reset(): Promise<void> {\n await super.reset();\n this.storedEncryptionProfile = undefined;\n this.store.reset();\n }\n\n /** @override parent method to reconfigure the enclave */\n async reconfigure(options: Partial<K> = {}): Promise<void> {\n await super.reconfigure(options);\n // Reconfigure MPC client if any signer information changed\n if (this.mpcClientInstance && options.walletType && options.walletAddress) {\n this.mpcClientInstance.reconfigure(\n options.walletType,\n options.walletAddress ?? \"\",\n options.walletPublicKey,\n );\n }\n }\n\n /**\n * Return a codec that encrypts/decrypts data using a key derived from the provider's user ID.\n *\n * This ensures that data is minimally obfuscated to avoid low-sophistication attacks.\n */\n private userIdObfuscationCodec(): PipeCodecArgs<string> {\n // oxlint-disable-next-line typescript/no-this-alias -- Needed for `this` in nested encode/decode functions\n const self = this;\n\n const toKey = (userId: string, salt: Uint8Array) =>\n syncScrypt(utf8Encode(userId), salt, 16384, 8, 1, nacl.secretbox.keyLength);\n\n return {\n encode(data: string): string {\n if (!self.options.userId) {\n throw new Error(\"User ID required for encryption\");\n }\n\n const dataBytes = utf8Encode(data); // Convert string to Uint8Array\n const nonce = nacl.randomBytes(nacl.secretbox.nonceLength);\n const salt = nacl.randomBytes(16);\n const key = toKey(self.options.userId, salt);\n const payload = nacl.secretbox(dataBytes, nonce, key);\n\n // Store salt + nonce + ciphertext\n const combined = new Uint8Array(salt.length + nonce.length + payload.length);\n combined.set(salt, 0);\n combined.set(nonce, salt.length);\n combined.set(payload, salt.length + nonce.length);\n\n return `0x${hexEncode(combined)}`;\n },\n\n decode(payload: string): string {\n if (!self.options.userId) {\n throw new Error(\"User ID required for decryption\");\n }\n\n if (payload.slice(0, 2) !== \"0x\") {\n throw new Error(`missing 0x prefix: ${payload}`);\n }\n\n const combined = hexDecode(payload.slice(2));\n const salt = combined.slice(0, 16);\n const nonce = combined.slice(16, 16 + nacl.secretbox.nonceLength);\n const ciphertext = combined.slice(16 + nacl.secretbox.nonceLength);\n\n const key = toKey(self.options.userId, salt);\n const result = nacl.secretbox.open(ciphertext, nonce, key);\n\n if (!result) throw new Error(\"Failed to decrypt data\");\n\n return utf8Decode(result); // Convert Uint8Array back to string\n },\n };\n }\n /** @see parent method extended with loading the profile from the store */\n async load(): Promise<void> {\n await super.load();\n\n const userId = await this.store.get<string>(STORAGE_KEYS.USER_ID);\n if (userId) this.options.userId = userId;\n\n let password = await this.storeObfuscated.get<string>(STORAGE_KEYS.OBFUSCATED_PASSWORD);\n if (!password) {\n password = await this.store.get<string>(STORAGE_KEYS.DEPRECATED___PASSWORD);\n if (!password) return;\n\n await this.storeObfuscated.set(STORAGE_KEYS.OBFUSCATED_PASSWORD, password);\n }\n await this.store.delete(STORAGE_KEYS.DEPRECATED___PASSWORD);\n\n let encryptionSecretKey = await this.storeObfuscatedBase64.get<Uint8Array>(\n STORAGE_KEYS.OBFUSCATED_BASE64_ENCRYPTION_SECRET_KEY,\n );\n if (!encryptionSecretKey) {\n encryptionSecretKey = await this.storeBase64.get<Uint8Array>(\n STORAGE_KEYS.DEPRECATED___ENCRYPTION_SECRET_KEY,\n );\n if (!encryptionSecretKey) return;\n\n await this.storeObfuscatedBase64.set(\n STORAGE_KEYS.OBFUSCATED_BASE64_ENCRYPTION_SECRET_KEY,\n encryptionSecretKey,\n );\n }\n await this.store.delete(STORAGE_KEYS.DEPRECATED___ENCRYPTION_SECRET_KEY);\n // Even older version.\n await this.store.delete(STORAGE_KEYS.DEPRECATED___ENCRYPTION_PRIVATE_KEY);\n\n if (!password || !userId || !encryptionSecretKey) {\n return;\n }\n\n let encryptionPasswordStore = await this.store.get<EncryptionPasswordStore>(\n STORAGE_KEYS.ENCRYPTION_PASSWORD_STORE,\n );\n\n // Migration from \"password\" to \"user\"\n // TODO: Remove this after a while\n if (!encryptionPasswordStore || (encryptionPasswordStore as string) === \"password\") {\n encryptionPasswordStore = \"user\";\n await this.store.set<EncryptionPasswordStore>(\n STORAGE_KEYS.ENCRYPTION_PASSWORD_STORE,\n encryptionPasswordStore,\n );\n }\n\n this.storedEncryptionProfile = {\n userId,\n password,\n keyPair: nacl.box.keyPair.fromSecretKey(encryptionSecretKey),\n encryptionPasswordStore,\n };\n }\n\n /**\n * Encrypts a message to a receiver.\n * This method also checks if the user is authorized to use the keys.\n *\n * @param message - The message to encrypt.\n * @param receiverPublicKey - The public key of the receiver.\n *\n * @returns The encrypted message.\n */\n async encrypt(\n message: Uint8Array,\n receiverPublicKey: Uint8Array,\n ): Promise<{ content: Uint8Array; encryptorPublicKey: Uint8Array }> {\n const { keyPair } = await this.getPrivateEncryptionProfile();\n return encrypt(message, keyPair.publicKey, receiverPublicKey);\n }\n\n /**\n * Decrypts a message from a sender.\n * This method also checks if the user is authorized to use the keys.\n *\n * @param message - The message to decrypt.\n * @param senderPublicKey - The public key of the sender.\n *\n * @returns The decrypted message.\n */\n async decrypt(\n message: Uint8Array,\n senderPublicKey: Uint8Array,\n ): Promise<Uint8Array<ArrayBufferLike>> {\n const { keyPair } = await this.getPrivateEncryptionProfile();\n return decrypt(message, keyPair, senderPublicKey);\n }\n\n /**\n * @see BaseProvider#getPrivateEncryptionProfile\n */\n async getPrivateEncryptionProfile(skipGuard = false): Promise<PrivateEncryptionProfile> {\n // In case there is a no key pair, which matches we don't need a new one.\n if (this.storedEncryptionProfile) {\n let canBeUsed = this.storedEncryptionProfile.userId === this.userId;\n\n if (canBeUsed && !skipGuard) {\n // When users matches, we also need to check\n // if origin is authorized to use the keys.\n canBeUsed = await this.guardKeys();\n }\n\n if (canBeUsed) {\n return this.storedEncryptionProfile;\n }\n\n // Something did not match, we need to create a new key pair\n // and reset the enclave.\n await this.reset();\n }\n\n // The stored profile can't be used, or we have to create a new one.\n let password: string | undefined;\n let encryptionPasswordStore: EncryptionPasswordStore | undefined;\n\n const context = await this.getPasswordContext();\n\n if (context.encryptionPasswordStore === \"user\") {\n await this.store.setRememberDuration(context.duration);\n\n password = context.password;\n encryptionPasswordStore = context.encryptionPasswordStore;\n }\n\n if (context.encryptionPasswordStore === \"mpc\") {\n // TODO: This is resetting duration, but should?\n await this.store.setRememberDuration(undefined);\n\n password = await this.ensureMPCPassword();\n encryptionPasswordStore = \"mpc\";\n }\n\n if (!password || !encryptionPasswordStore) {\n throw new Error(\"Password or encryption password store is not found\");\n }\n\n return this.createEncryptionProfileFromPassword(password, this.userId, encryptionPasswordStore);\n }\n\n /** @see BaseProvider#ensureUserEncryptionProfile */\n async ensureUserEncryptionProfile(): Promise<PublicEncryptionProfile> {\n const { keyPair, encryptionPasswordStore, userId } = await this.getPrivateEncryptionProfile();\n\n return {\n userId,\n userEncryptionPublicKey: base64Encode(keyPair.publicKey),\n encryptionPasswordStore: encryptionPasswordStore,\n };\n }\n\n /**\n * This method needs to check `options` and should derive the password context from it.\n *\n * @returns The password context.\n */\n async getPasswordContext(): Promise<PasswordContext | MPCPasswordContext> {\n throw new Error(\"Method 'getPasswordContext' has to be implemented in the subclass.\");\n }\n\n /**\n * Creates and store encryption profile from a password.\n *\n * @param password - The password to use.\n * @param userId - The user id to use.\n * @param encryptionPasswordStore - The encryption password store to use.\n *\n * @returns The encryption profile.\n */\n async createEncryptionProfileFromPassword(\n password: string,\n userId: string,\n encryptionPasswordStore: EncryptionPasswordStore,\n ): Promise<PrivateEncryptionProfile> {\n const secretKey = await keyDerivation(password, userId);\n\n const keyPair = nacl.box.keyPair.fromSecretKey(secretKey);\n\n await this.store.set(STORAGE_KEYS.USER_ID, userId);\n await this.storeObfuscated.set(STORAGE_KEYS.OBFUSCATED_PASSWORD, password);\n await this.store.delete(STORAGE_KEYS.DEPRECATED___PASSWORD);\n await this.store.set(STORAGE_KEYS.ENCRYPTION_PASSWORD_STORE, encryptionPasswordStore);\n await this.storeObfuscatedBase64.set(\n STORAGE_KEYS.OBFUSCATED_BASE64_ENCRYPTION_SECRET_KEY,\n keyPair.secretKey,\n );\n await this.store.delete(STORAGE_KEYS.DEPRECATED___ENCRYPTION_SECRET_KEY);\n await this.storeBase64.set(STORAGE_KEYS.ENCRYPTION_PUBLIC_KEY, keyPair.publicKey);\n\n this.storedEncryptionProfile = {\n userId,\n password,\n keyPair,\n encryptionPasswordStore,\n };\n\n return this.storedEncryptionProfile;\n }\n\n protected async ensureMPCPassword(): Promise<string> {\n if (this.options?.mode !== \"new\") {\n const { status: downloadStatus, secret: downloadedPassword } = await this.downloadSecret();\n\n if (downloadStatus === \"ok\" && downloadedPassword) {\n return utf8Decode(downloadedPassword);\n }\n\n throw Error(\"A secret might be stored at MPC ZK nodes, but can't be obtained\");\n }\n\n const password = generatePassword();\n const { status: uploadStatus } = await this.uploadSecret(password);\n\n if (uploadStatus !== \"success\") {\n throw Error(`A secret upload failed with status: ${uploadStatus}`);\n }\n\n return password;\n }\n\n private get mpcClient(): MPCClient {\n if (!this.mpcClientInstance) {\n throw new Error(\"MPC client is not initialized\");\n }\n return this.mpcClientInstance;\n }\n\n private async downloadSecret(): Promise<{\n status: string;\n secret: Buffer<ArrayBufferLike> | undefined;\n }> {\n // I really don't like this, I guess the walletAddress should be stored in the store.\n if (!this.options.walletAddress) {\n throw new Error(\"walletAddress is not found\");\n }\n\n const ephemeralKeyPair = nacl.box.keyPair();\n\n const downloadRequest = this.mpcClient.downloadRequest(ephemeralKeyPair.publicKey);\n\n const messageToSign = this.mpcClient.downloadMessageToSign(\n downloadRequest,\n ) as DownloadMessageToSign;\n\n const signedMessage = await this.signTypedData(\n messageToSign.domain,\n messageToSign.types,\n messageToSign.value,\n );\n\n return this.mpcClient.downloadSecret(\n this.userId,\n downloadRequest,\n signedMessage,\n ephemeralKeyPair.secretKey,\n );\n }\n\n private async uploadSecret(secret: string): Promise<{ status: string }> {\n if (!this.options.walletAddress) {\n console.error(\"signerAddress is not found\");\n return { status: \"no-signer-address\" };\n }\n\n const blindedShares = this.mpcClient.getBlindedShares(Buffer.from(secret, \"utf8\"));\n const uploadRequest = this.mpcClient.uploadRequest(blindedShares);\n const messageToSign = this.mpcClient.uploadMessageToSign(uploadRequest) as UploadMessageToSign;\n\n const signedMessage = await this.signTypedData(\n // oxlint-disable-next-line typescript/no-explicit-any -- TODO: Change this when we know how to MPC & other chains\n messageToSign.domain as any,\n // oxlint-disable-next-line typescript/no-explicit-any -- TODO: Change this when we know how to MPC & other chains\n messageToSign.types as any,\n // oxlint-disable-next-line typescript/no-explicit-any -- TODO: Change this when we know how to MPC & other chains\n messageToSign.value as any,\n );\n\n return this.mpcClient.uploadSecret(this.userId, uploadRequest, signedMessage, blindedShares);\n }\n\n async addAddressMessageToSign(\n address: string,\n publicKey: string | undefined,\n addressToAddType: string,\n ): Promise<AddAddressMessageToSign> {\n return this.mpcClient.addAddressMessageToSign(\n address,\n publicKey,\n addressToAddType,\n ) as AddAddressMessageToSign;\n }\n\n async removeAddressMessageToSign(\n address: string,\n publicKey: string | undefined,\n addressToRemoveType: string,\n ): Promise<RemoveAddressMessageToSign> {\n return this.mpcClient.removeAddressMessageToSign(\n address,\n publicKey,\n addressToRemoveType,\n ) as RemoveAddressMessageToSign;\n }\n\n async addAddressToMpcSecret(\n userId: string,\n message: AddAddressSignatureMessage,\n signature: string,\n ): Promise<string> {\n return this.mpcClient.addAddress(userId, message, signature);\n }\n\n async removeAddressFromMpcSecret(\n userId: string,\n message: RemoveAddressSignatureMessage,\n signature: string,\n ): Promise<string> {\n return this.mpcClient.removeAddress(userId, message, signature);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"local.mjs","names":["MPCClient"],"sources":["../src/local.ts"],"sourcesContent":["import type { EncryptionPasswordStore } from \"@idos-network/kwil-infra/actions\";\n\nimport {\n base64Codec,\n base64Encode,\n hexDecode,\n hexEncode,\n utf8Decode,\n utf8Encode,\n} from \"@idos-network/utils/codecs\";\nimport { generatePassword } from \"@idos-network/utils/cryptography\";\nimport { decrypt, encrypt, keyDerivation } from \"@idos-network/utils/encryption\";\nimport { LocalStorageStore, type PipeCodecArgs, type Store } from \"@idos-network/utils/store\";\nimport { syncScrypt } from \"scrypt-js\";\nimport nacl from \"tweetnacl\";\n\nimport type {\n AddAddressMessageToSign,\n AddAddressSignatureMessage,\n DownloadMessageToSign,\n RemoveAddressMessageToSign,\n RemoveAddressSignatureMessage,\n UploadMessageToSign,\n} from \"./mpc/types\";\nimport type {\n EnclaveOptions,\n MPCPasswordContext,\n PasswordContext,\n PrivateEncryptionProfile,\n PublicEncryptionProfile,\n} from \"./types\";\n\nimport { BaseProvider } from \"./base\";\nimport { STORAGE_KEYS } from \"./keys\";\nimport { Client as MPCClient } from \"./mpc/client\";\n\nexport interface LocalEnclaveOptions extends EnclaveOptions {\n store?: Store;\n allowedEncryptionStores?: EncryptionPasswordStore[];\n mpcConfiguration?: {\n nodeUrl: string;\n contractAddress: string;\n numMalicious: number;\n numNodes: number;\n numToReconstruct: number;\n };\n}\n\nexport class LocalEnclave<\n K extends LocalEnclaveOptions = LocalEnclaveOptions,\n> extends BaseProvider<K> {\n protected allowedEncryptionStores: EncryptionPasswordStore[];\n\n // Store for data\n protected store: Store;\n protected storeBase64: Store;\n protected storeObfuscated: Store;\n protected storeObfuscatedBase64: Store;\n\n // In case of MPC usage\n protected mpcClientInstance?: MPCClient;\n\n // Stored key pair and user id for that key pair\n // those are most likely loaded from the store\n // during the load() method.\n protected storedEncryptionProfile?: PrivateEncryptionProfile;\n\n constructor(options: K) {\n super(options);\n\n // By default, we only allow password auth method\n this.allowedEncryptionStores = options.allowedEncryptionStores ?? [\"user\"];\n this.store = options.store ?? new LocalStorageStore();\n this.storeObfuscated = this.store.pipeCodec(this.userIdObfuscationCodec());\n this.storeBase64 = this.store.pipeCodec(base64Codec);\n this.storeObfuscatedBase64 = this.store\n .pipeCodec(this.userIdObfuscationCodec())\n .pipeCodec(base64Codec);\n\n if (options.mpcConfiguration) {\n this.mpcClientInstance = new MPCClient(\n options.mpcConfiguration.nodeUrl,\n options.mpcConfiguration.contractAddress,\n options.mpcConfiguration.numMalicious,\n options.mpcConfiguration.numNodes,\n options.mpcConfiguration.numToReconstruct,\n // TODO: This is weird, we should not be forcing this\n options.walletType ?? \"EVM\",\n options.walletAddress ?? \"\",\n options.walletPublicKey,\n );\n }\n }\n\n /** @override parent method to reset the enclave */\n async reset(): Promise<void> {\n await super.reset();\n this.storedEncryptionProfile = undefined;\n await this.store.reset();\n }\n\n /** @override parent method to reconfigure the enclave */\n async reconfigure(options: Partial<K> = {}): Promise<void> {\n await super.reconfigure(options);\n // Reconfigure MPC client if any signer information changed\n if (this.mpcClientInstance && options.walletType && options.walletAddress) {\n this.mpcClientInstance.reconfigure(\n options.walletType,\n options.walletAddress ?? \"\",\n options.walletPublicKey,\n );\n }\n }\n\n /**\n * Return a codec that encrypts/decrypts data using a key derived from the provider's user ID.\n *\n * This ensures that data is minimally obfuscated to avoid low-sophistication attacks.\n */\n private userIdObfuscationCodec(): PipeCodecArgs<string> {\n // oxlint-disable-next-line typescript/no-this-alias -- Needed for `this` in nested encode/decode functions\n const self = this;\n\n const toKey = (userId: string, salt: Uint8Array) =>\n syncScrypt(utf8Encode(userId), salt, 16384, 8, 1, nacl.secretbox.keyLength);\n\n return {\n encode(data: string): string {\n if (!self.options.userId) {\n throw new Error(\"User ID required for encryption\");\n }\n\n const dataBytes = utf8Encode(data); // Convert string to Uint8Array\n const nonce = nacl.randomBytes(nacl.secretbox.nonceLength);\n const salt = nacl.randomBytes(16);\n const key = toKey(self.options.userId, salt);\n const payload = nacl.secretbox(dataBytes, nonce, key);\n\n // Store salt + nonce + ciphertext\n const combined = new Uint8Array(salt.length + nonce.length + payload.length);\n combined.set(salt, 0);\n combined.set(nonce, salt.length);\n combined.set(payload, salt.length + nonce.length);\n\n return `0x${hexEncode(combined)}`;\n },\n\n decode(payload: string): string {\n if (!self.options.userId) {\n throw new Error(\"User ID required for decryption\");\n }\n\n if (payload.slice(0, 2) !== \"0x\") {\n throw new Error(`missing 0x prefix: ${payload}`);\n }\n\n const combined = hexDecode(payload.slice(2));\n const salt = combined.slice(0, 16);\n const nonce = combined.slice(16, 16 + nacl.secretbox.nonceLength);\n const ciphertext = combined.slice(16 + nacl.secretbox.nonceLength);\n\n const key = toKey(self.options.userId, salt);\n const result = nacl.secretbox.open(ciphertext, nonce, key);\n\n if (!result) throw new Error(\"Failed to decrypt data\");\n\n return utf8Decode(result); // Convert Uint8Array back to string\n },\n };\n }\n /** @see parent method extended with loading the profile from the store */\n async load(): Promise<void> {\n await super.load();\n\n const userId = await this.store.get<string>(STORAGE_KEYS.USER_ID);\n if (userId) this.options.userId = userId;\n\n let password = await this.storeObfuscated.get<string>(STORAGE_KEYS.OBFUSCATED_PASSWORD);\n if (!password) {\n password = await this.store.get<string>(STORAGE_KEYS.DEPRECATED___PASSWORD);\n if (!password) return;\n\n await this.storeObfuscated.set(STORAGE_KEYS.OBFUSCATED_PASSWORD, password);\n }\n await this.store.delete(STORAGE_KEYS.DEPRECATED___PASSWORD);\n\n let encryptionSecretKey = await this.storeObfuscatedBase64.get<Uint8Array>(\n STORAGE_KEYS.OBFUSCATED_BASE64_ENCRYPTION_SECRET_KEY,\n );\n if (!encryptionSecretKey) {\n encryptionSecretKey = await this.storeBase64.get<Uint8Array>(\n STORAGE_KEYS.DEPRECATED___ENCRYPTION_SECRET_KEY,\n );\n if (!encryptionSecretKey) return;\n\n await this.storeObfuscatedBase64.set(\n STORAGE_KEYS.OBFUSCATED_BASE64_ENCRYPTION_SECRET_KEY,\n encryptionSecretKey,\n );\n }\n await this.store.delete(STORAGE_KEYS.DEPRECATED___ENCRYPTION_SECRET_KEY);\n // Even older version.\n await this.store.delete(STORAGE_KEYS.DEPRECATED___ENCRYPTION_PRIVATE_KEY);\n\n if (!password || !userId || !encryptionSecretKey) {\n return;\n }\n\n let encryptionPasswordStore = await this.store.get<EncryptionPasswordStore>(\n STORAGE_KEYS.ENCRYPTION_PASSWORD_STORE,\n );\n\n // Migration from \"password\" to \"user\"\n // TODO: Remove this after a while\n if (!encryptionPasswordStore || (encryptionPasswordStore as string) === \"password\") {\n encryptionPasswordStore = \"user\";\n await this.store.set<EncryptionPasswordStore>(\n STORAGE_KEYS.ENCRYPTION_PASSWORD_STORE,\n encryptionPasswordStore,\n );\n }\n\n this.storedEncryptionProfile = {\n userId,\n password,\n keyPair: nacl.box.keyPair.fromSecretKey(encryptionSecretKey),\n encryptionPasswordStore,\n };\n }\n\n /**\n * Encrypts a message to a receiver.\n * This method also checks if the user is authorized to use the keys.\n *\n * @param message - The message to encrypt.\n * @param receiverPublicKey - The public key of the receiver.\n *\n * @returns The encrypted message.\n */\n async encrypt(\n message: Uint8Array,\n receiverPublicKey: Uint8Array,\n ): Promise<{ content: Uint8Array; encryptorPublicKey: Uint8Array }> {\n const { keyPair } = await this.getPrivateEncryptionProfile();\n return encrypt(message, keyPair.publicKey, receiverPublicKey);\n }\n\n /**\n * Decrypts a message from a sender.\n * This method also checks if the user is authorized to use the keys.\n *\n * @param message - The message to decrypt.\n * @param senderPublicKey - The public key of the sender.\n *\n * @returns The decrypted message.\n */\n async decrypt(\n message: Uint8Array,\n senderPublicKey: Uint8Array,\n ): Promise<Uint8Array<ArrayBufferLike>> {\n const { keyPair } = await this.getPrivateEncryptionProfile();\n return decrypt(message, keyPair, senderPublicKey);\n }\n\n /**\n * @see BaseProvider#getPrivateEncryptionProfile\n */\n async getPrivateEncryptionProfile(skipGuard = false): Promise<PrivateEncryptionProfile> {\n // Remember duration is a key-use check. A long-lived iframe keeps this profile\n // in memory, so construction-time store expiry is not enough.\n if (this.storedEncryptionProfile && (await this.store.hasRememberDurationElapsed())) {\n await this.reset();\n }\n\n if (this.storedEncryptionProfile?.userId === this.userId) {\n // A matching cached profile still needs origin authorization before key use.\n // Denying it must keep the profile and the allowlist; only a different user resets.\n if (!skipGuard && !(await this.guardKeys())) {\n throw new Error(\"Origin is not authorized to use the keys\");\n }\n\n return this.storedEncryptionProfile;\n }\n\n if (this.storedEncryptionProfile) {\n await this.reset();\n }\n\n if (this.options.encryptionPasswordStore === \"mm\") {\n throw new Error(\n \"MM encryption profiles require an externally supplied encryption private key\",\n );\n }\n\n let password: string | undefined;\n let encryptionPasswordStore: EncryptionPasswordStore | undefined;\n\n const context = await this.getPasswordContext();\n\n if (context.encryptionPasswordStore === \"user\") {\n await this.store.setRememberDuration(context.duration);\n\n password = context.password;\n encryptionPasswordStore = context.encryptionPasswordStore;\n }\n\n if (context.encryptionPasswordStore === \"mpc\") {\n // TODO: This is resetting duration, but should?\n await this.store.setRememberDuration(undefined);\n\n password = await this.ensureMPCPassword();\n encryptionPasswordStore = \"mpc\";\n }\n\n if (!password || !encryptionPasswordStore) {\n throw new Error(\"Password or encryption password store is not found\");\n }\n\n const profile = await this.createEncryptionProfileFromPassword(\n password,\n this.userId,\n encryptionPasswordStore,\n );\n\n // Same origin check as the cached path. Password or MPC success is not authorization.\n if (!skipGuard && !(await this.guardKeys())) {\n throw new Error(\"Origin is not authorized to use the keys\");\n }\n\n return profile;\n }\n\n /** @see BaseProvider#ensureUserEncryptionProfile */\n async ensureUserEncryptionProfile(): Promise<PublicEncryptionProfile> {\n const { keyPair, encryptionPasswordStore, userId } = await this.getPrivateEncryptionProfile();\n\n return {\n userId,\n userEncryptionPublicKey: base64Encode(keyPair.publicKey),\n encryptionPasswordStore: encryptionPasswordStore,\n };\n }\n\n /**\n * This method needs to check `options` and should derive the password context from it.\n *\n * @returns The password context.\n */\n async getPasswordContext(): Promise<PasswordContext | MPCPasswordContext> {\n throw new Error(\"Method 'getPasswordContext' has to be implemented in the subclass.\");\n }\n\n /**\n * Creates and store encryption profile from a password.\n *\n * @param password - The password to use.\n * @param userId - The user id to use.\n * @param encryptionPasswordStore - The encryption password store to use.\n *\n * @returns The encryption profile.\n */\n async createEncryptionProfileFromPassword(\n password: string,\n userId: string,\n encryptionPasswordStore: EncryptionPasswordStore,\n ): Promise<PrivateEncryptionProfile> {\n const secretKey = await keyDerivation(password, userId);\n\n const keyPair = nacl.box.keyPair.fromSecretKey(secretKey);\n\n const expectedPublicKey = this.options.expectedUserEncryptionPublicKey;\n if (expectedPublicKey && base64Encode(keyPair.publicKey) !== expectedPublicKey) {\n throw new Error(\n \"Derived encryption public key does not match expectedUserEncryptionPublicKey\",\n );\n }\n\n await this.store.set(STORAGE_KEYS.USER_ID, userId);\n await this.storeObfuscated.set(STORAGE_KEYS.OBFUSCATED_PASSWORD, password);\n await this.store.delete(STORAGE_KEYS.DEPRECATED___PASSWORD);\n await this.store.set(STORAGE_KEYS.ENCRYPTION_PASSWORD_STORE, encryptionPasswordStore);\n await this.storeObfuscatedBase64.set(\n STORAGE_KEYS.OBFUSCATED_BASE64_ENCRYPTION_SECRET_KEY,\n keyPair.secretKey,\n );\n await this.store.delete(STORAGE_KEYS.DEPRECATED___ENCRYPTION_SECRET_KEY);\n await this.storeBase64.set(STORAGE_KEYS.ENCRYPTION_PUBLIC_KEY, keyPair.publicKey);\n\n this.storedEncryptionProfile = {\n userId,\n password,\n keyPair,\n encryptionPasswordStore,\n };\n\n return this.storedEncryptionProfile;\n }\n\n protected async ensureMPCPassword(): Promise<string> {\n if (this.options?.mode !== \"new\") {\n const { status: downloadStatus, secret: downloadedPassword } = await this.downloadSecret();\n\n if (downloadStatus === \"ok\" && downloadedPassword) {\n return utf8Decode(downloadedPassword);\n }\n\n throw Error(\"A secret might be stored at MPC ZK nodes, but can't be obtained\");\n }\n\n const password = generatePassword();\n const { status: uploadStatus } = await this.uploadSecret(password);\n\n if (uploadStatus !== \"success\") {\n throw Error(`A secret upload failed with status: ${uploadStatus}`);\n }\n\n return password;\n }\n\n private get mpcClient(): MPCClient {\n if (!this.mpcClientInstance) {\n throw new Error(\"MPC client is not initialized\");\n }\n return this.mpcClientInstance;\n }\n\n private async downloadSecret(): Promise<{\n status: string;\n secret: Buffer<ArrayBufferLike> | undefined;\n }> {\n // I really don't like this, I guess the walletAddress should be stored in the store.\n if (!this.options.walletAddress) {\n throw new Error(\"walletAddress is not found\");\n }\n\n const ephemeralKeyPair = nacl.box.keyPair();\n\n const downloadRequest = this.mpcClient.downloadRequest(ephemeralKeyPair.publicKey);\n\n const messageToSign = this.mpcClient.downloadMessageToSign(\n downloadRequest,\n ) as DownloadMessageToSign;\n\n const signedMessage = await this.signTypedData(\n messageToSign.domain,\n messageToSign.types,\n messageToSign.value,\n );\n\n return this.mpcClient.downloadSecret(\n this.userId,\n downloadRequest,\n signedMessage,\n ephemeralKeyPair.secretKey,\n );\n }\n\n private async uploadSecret(secret: string): Promise<{ status: string }> {\n if (!this.options.walletAddress) {\n console.error(\"signerAddress is not found\");\n return { status: \"no-signer-address\" };\n }\n\n const blindedShares = this.mpcClient.getBlindedShares(Buffer.from(secret, \"utf8\"));\n const uploadRequest = this.mpcClient.uploadRequest(blindedShares);\n const messageToSign = this.mpcClient.uploadMessageToSign(uploadRequest) as UploadMessageToSign;\n\n const signedMessage = await this.signTypedData(\n // oxlint-disable-next-line typescript/no-explicit-any -- TODO: Change this when we know how to MPC & other chains\n messageToSign.domain as any,\n // oxlint-disable-next-line typescript/no-explicit-any -- TODO: Change this when we know how to MPC & other chains\n messageToSign.types as any,\n // oxlint-disable-next-line typescript/no-explicit-any -- TODO: Change this when we know how to MPC & other chains\n messageToSign.value as any,\n );\n\n return this.mpcClient.uploadSecret(this.userId, uploadRequest, signedMessage, blindedShares);\n }\n\n async addAddressMessageToSign(\n address: string,\n publicKey: string | undefined,\n addressToAddType: string,\n ): Promise<AddAddressMessageToSign> {\n return this.mpcClient.addAddressMessageToSign(\n address,\n publicKey,\n addressToAddType,\n ) as AddAddressMessageToSign;\n }\n\n async removeAddressMessageToSign(\n address: string,\n publicKey: string | undefined,\n addressToRemoveType: string,\n ): Promise<RemoveAddressMessageToSign> {\n return this.mpcClient.removeAddressMessageToSign(\n address,\n publicKey,\n addressToRemoveType,\n ) as RemoveAddressMessageToSign;\n }\n\n async addAddressToMpcSecret(\n userId: string,\n message: AddAddressSignatureMessage,\n signature: string,\n ): Promise<string> {\n return this.mpcClient.addAddress(userId, message, signature);\n }\n\n async removeAddressFromMpcSecret(\n userId: string,\n message: RemoveAddressSignatureMessage,\n signature: string,\n ): Promise<string> {\n return this.mpcClient.removeAddress(userId, message, signature);\n }\n}\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { C as UpdateWalletsSignatureMessage, S as UpdateWalletsRequest, T as UploadSignatureMessage, _ as RemoveAddressRequest, a as Address, b as UPDATE_TYPES, c as Bytes32, d as DownloadRequest, f as DownloadSignatureMessage, g as RemoveAddressMessageToSign, h as REMOVE_ADDRESS_TYPES, i as AddAddressSignatureMessage, l as DOWNLOAD_TYPES, m as PbcAddress, n as AddAddressMessageToSign, o as Bytes, p as EncryptedShare, r as AddAddressRequest, s as Bytes24, t as ADD_ADDRESS_TYPES, u as DownloadMessageToSign, v as RemoveAddressSignatureMessage, w as UploadMessageToSign, x as UPLOAD_TYPES, y as Sharing } from "../types-DKsOwtWL.mjs";
2
- import { t as Client } from "../client-Bu0aO5sT.mjs";
1
+ import { C as UpdateWalletsSignatureMessage, S as UpdateWalletsRequest, T as UploadSignatureMessage, _ as RemoveAddressRequest, a as Address, b as UPDATE_TYPES, c as Bytes32, d as DownloadRequest, f as DownloadSignatureMessage, g as RemoveAddressMessageToSign, h as REMOVE_ADDRESS_TYPES, i as AddAddressSignatureMessage, l as DOWNLOAD_TYPES, m as PbcAddress, n as AddAddressMessageToSign, o as Bytes, p as EncryptedShare, r as AddAddressRequest, s as Bytes24, t as ADD_ADDRESS_TYPES, u as DownloadMessageToSign, v as RemoveAddressSignatureMessage, w as UploadMessageToSign, x as UPLOAD_TYPES, y as Sharing } from "../types-Ck9Ec1Pa.mjs";
2
+ import { t as Client } from "../client-Ci4XBJXn.mjs";
3
3
  export { ADD_ADDRESS_TYPES, AddAddressMessageToSign, AddAddressRequest, AddAddressSignatureMessage, Address, Bytes, Bytes24, Bytes32, Client, DOWNLOAD_TYPES, DownloadMessageToSign, DownloadRequest, DownloadSignatureMessage, EncryptedShare, PbcAddress, REMOVE_ADDRESS_TYPES, RemoveAddressMessageToSign, RemoveAddressRequest, RemoveAddressSignatureMessage, Sharing, UPDATE_TYPES, UPLOAD_TYPES, UpdateWalletsRequest, UpdateWalletsSignatureMessage, UploadMessageToSign, UploadSignatureMessage };
@@ -1,2 +1 @@
1
- import { a as UPDATE_TYPES, i as REMOVE_ADDRESS_TYPES, n as ADD_ADDRESS_TYPES, o as UPLOAD_TYPES, r as DOWNLOAD_TYPES, t as Client } from "../client-rcvBXslm.mjs";
2
- export { ADD_ADDRESS_TYPES, Client, DOWNLOAD_TYPES, REMOVE_ADDRESS_TYPES, UPDATE_TYPES, UPLOAD_TYPES };
1
+ import{a as e,i as t,n,o as r,r as i,t as a}from"../client-Dqb0xbdb.mjs";export{n as ADD_ADDRESS_TYPES,a as Client,i as DOWNLOAD_TYPES,t as REMOVE_ADDRESS_TYPES,e as UPDATE_TYPES,r as UPLOAD_TYPES};
@@ -1,5 +1,4 @@
1
1
  import { TypedDataDomain, TypedDataField } from "ethers";
2
-
3
2
  //#region src/mpc/types.d.ts
4
3
  type PbcAddress = string;
5
4
  type Bytes32 = string;
@@ -70,4 +69,4 @@ type RemoveAddressMessageToSign = {
70
69
  };
71
70
  //#endregion
72
71
  export { UpdateWalletsSignatureMessage as C, UpdateWalletsRequest as S, UploadSignatureMessage as T, RemoveAddressRequest as _, Address as a, UPDATE_TYPES as b, Bytes32 as c, DownloadRequest as d, DownloadSignatureMessage as f, RemoveAddressMessageToSign as g, REMOVE_ADDRESS_TYPES as h, AddAddressSignatureMessage as i, DOWNLOAD_TYPES as l, PbcAddress as m, AddAddressMessageToSign as n, Bytes as o, EncryptedShare as p, AddAddressRequest as r, Bytes24 as s, ADD_ADDRESS_TYPES as t, DownloadMessageToSign as u, RemoveAddressSignatureMessage as v, UploadMessageToSign as w, UPLOAD_TYPES as x, Sharing as y };
73
- //# sourceMappingURL=types-DKsOwtWL.d.mts.map
72
+ //# sourceMappingURL=types-Ck9Ec1Pa.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-Ck9Ec1Pa.d.mts","names":[],"sources":["../src/mpc/types.ts"],"mappings":";;KAEY;KACA;KACA;KACA;KACA;cAEC,cAAc,eAAe;cAO7B,gBAAgB,eAAe;cAQ/B,cAAc,eAAe;cAO7B,mBAAmB,eAAe;cAQlC,sBAAsB,eAAe;UAQjC;EACf,mBAAmB;EACnB,sBAAsB;;UAGP;EACf,mBAAmB;EACnB,sBAAsB;EACtB,YAAY;;UAGG;EACf,oBAAoB;EACpB;EACA,YAAY;;KAGF,kBAAkB;UAEb;EACf,oBAAoB;EACpB,gBAAgB;EAChB;;KAGU,oBAAoB;UAEf;EACf,oBAAoB;EACpB,mBAAmB;EACnB;;KAGU,uBAAuB;UAElB;EACf,sBAAsB;EACtB;;KAGU,uBAAuB;UAElB;EACf,iBAAiB;EACjB,YAAY;EACZ,OAAO;;KAGG;EACV,QAAQ;EACR,OAAO,eAAe;EACtB,OAAO;;KAGG;EACV,QAAQ;EACR,OAAO,eAAe;EACtB,OAAO;;KAGG;EACV,QAAQ;EACR,OAAO,eAAe;EACtB,OAAO;;KAGG;EACV,QAAQ;EACR,OAAO,eAAe;EACtB,OAAO"}