@idos-network/enclave 1.1.0 → 1.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.
@@ -1182,7 +1182,8 @@ var Client = class Client {
1182
1182
  async getEngines() {
1183
1183
  if (this.engines === void 0) {
1184
1184
  const rawState = await new ChainControllerApi(new Configuration({ basePath: this.baseUrl })).getContract({ address: this.contractAddress });
1185
- this.engines = deserializeState(Buffer.from(rawState.serializedContract, "base64")).nodes.map((value) => new EngineClient(value.endpoint, this.contractAddress, this.walletType));
1185
+ const state = deserializeState(Buffer.from(rawState.serializedContract, "base64"));
1186
+ this.engines = state.nodes.map((value) => new EngineClient(value.endpoint, this.contractAddress, this.walletType));
1186
1187
  }
1187
1188
  return this.engines;
1188
1189
  }
@@ -1193,4 +1194,4 @@ var Client = class Client {
1193
1194
  //#endregion
1194
1195
  export { UPDATE_TYPES as a, REMOVE_ADDRESS_TYPES as i, ADD_ADDRESS_TYPES as n, UPLOAD_TYPES as o, DOWNLOAD_TYPES as r, Client as t };
1195
1196
 
1196
- //# sourceMappingURL=client-BSkUuHYm.mjs.map
1197
+ //# sourceMappingURL=client-rcvBXslm.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"client-BSkUuHYm.mjs","names":[],"sources":["../src/mpc/api.ts","../src/mpc/engine-client.ts","../src/mpc/generated/IdosContract.ts","../src/mpc/secretsharing/polynomial.ts","../src/mpc/secretsharing/f256.ts","../src/mpc/secretsharing/lagrange.ts","../src/mpc/secretsharing/shamir-secret-shares.ts","../src/mpc/types.ts","../src/mpc/client.ts"],"sourcesContent":["const postHeaders = {\n Accept: \"application/json, text/plain, */*\",\n \"Content-Type\": \"application/json\",\n};\n\nconst getHeaders = {\n Accept: \"application/json, text/plain, */*\",\n};\n\nexport type RequestType = \"GET\" | \"PUT\" | \"POST\" | \"PATCH\";\n\nfunction buildOptions<T>(method: RequestType, headers: RequestInit[\"headers\"], entityBytes: T) {\n const result: RequestInit = { method, headers, body: null };\n\n if (entityBytes != null) {\n result.body = JSON.stringify(entityBytes);\n }\n return result;\n}\n\n/**\n * Make a http get-request.\n *\n * @param url the url to request.\n * @return a promise containing the result of the get request.\n */\nexport function getRequest<R>(url: string): Promise<{ status: string; body: R | undefined }> {\n const options = buildOptions(\"GET\", getHeaders, null);\n return handleFetch<R>(fetch(url, options));\n}\n\n/**\n * Make a http put-request.\n *\n * @param url the url to request.\n * @param object the object to put.\n * @param headers\n * @return a promise containing whether the put succeeded or not.\n */\nexport function putRequest<T>(\n url: string,\n object: T,\n headers?: Record<string, string>,\n): Promise<string> {\n const options = buildOptions(\"PUT\", { ...postHeaders, ...headers }, object);\n return fetch(url, options)\n .then(async (response) => {\n const responseClone = response.clone();\n const responseBody = await responseClone.text();\n console.log({ responseCode: response.status, responseBody });\n return response.status.toString();\n })\n .catch((error) => {\n console.error(error);\n return error;\n });\n}\n\n/**\n * Make a http patch-request.\n *\n * @param url the url to request.\n * @param object the object to put.\n * @param headers\n * @return a promise containing whether the put succeeded or not.\n */\nexport function patchRequest<T>(\n url: string,\n object: T,\n headers?: RequestInit[\"headers\"],\n): Promise<string> {\n const options = buildOptions(\"PATCH\", { ...postHeaders, ...headers }, object);\n return fetch(url, options)\n .then(async (response) => {\n const responseClone = response.clone();\n const responseBody = await responseClone.text();\n console.log({ responseCode: response.status, responseBody });\n return response.status.toString();\n })\n .catch((error) => {\n console.error(error);\n return error;\n });\n}\n\n/**\n * Make a http post-request.\n *\n * @param url the url to request.\n * @param object the object to post.\n * @param headers\n * @return a promise containing the result of the post request.\n */\nexport function postRequest<T, R>(\n url: string,\n object: T,\n headers?: Record<string, string>,\n): Promise<{ status: string; body: R | undefined }> {\n const options = buildOptions(\"POST\", { ...postHeaders, ...headers }, object);\n return handleFetch<R>(fetch(url, options));\n}\n\nfunction handleFetch<T>(\n promise: Promise<Response>,\n): Promise<{ status: string; body: T | undefined }> {\n return promise\n .then(async (response) => {\n const responseClone = response.clone();\n const responseBody = await responseClone.text();\n console.log({ responseCode: response.status, responseBody });\n\n if (response.status === 200) {\n const data = (await response.json()) as T;\n return { status: response.status.toString(), body: data };\n }\n return { status: response.status.toString(), body: undefined };\n })\n .catch((error) => {\n console.error(error);\n return { status: \"fetch-error\", body: undefined };\n });\n}\n","import type { WalletType } from \"@idos-network/kwil-infra/actions\";\nimport { ethers } from \"ethers\";\nimport nacl from \"tweetnacl\";\nimport { patchRequest, postRequest, putRequest } from \"./api\";\nimport type {\n AddAddressRequest,\n Bytes,\n DownloadRequest,\n EncryptedShare,\n PbcAddress,\n RemoveAddressRequest,\n Sharing,\n UpdateWalletsRequest,\n} from \"./types\";\n\nexport class EngineClient {\n private readonly baseUrl: string;\n private readonly contractAddress: PbcAddress;\n private readonly walletType: WalletType;\n\n constructor(baseUrl: string, contractAddress: PbcAddress, walletType: WalletType) {\n this.contractAddress = contractAddress;\n this.baseUrl = baseUrl;\n this.walletType = walletType;\n }\n\n private getAuthHeader(signature: string): Record<string, string> {\n let prefix: string;\n switch (this.walletType) {\n case \"EVM\":\n prefix = \"eip712\";\n break;\n case \"NEAR\":\n prefix = \"NEAR\";\n break;\n case \"XRPL\":\n prefix = \"XRPL\";\n break;\n case \"FaceSign\":\n prefix = \"FACESIGN\";\n break;\n default:\n prefix = \"eip712\"; // fallback to eip712 for unknown types\n }\n\n return {\n Authorization: `${prefix} ${signature}`,\n };\n }\n\n public async sendUpload(id: string, uploadRequest: Sharing, signature: Bytes): Promise<string> {\n const authHeader = this.getAuthHeader(signature);\n const url = `${this.baseUrl}/offchain/${this.contractAddress}/shares/${id}`;\n const status = await putRequest(url, uploadRequest, authHeader);\n if (status !== \"201\") {\n throw new Error(`Error uploading share to ${this.contractAddress} at ${url}`);\n }\n return status;\n }\n\n public async sendDownload(\n id: string,\n downloadRequest: DownloadRequest,\n signature: Bytes,\n ): Promise<{ status: string; body: EncryptedShare | undefined }> {\n const authHeader = this.getAuthHeader(signature);\n const url = `${this.baseUrl}/offchain/${this.contractAddress}/shares/${id}`;\n return await postRequest(url, downloadRequest, authHeader);\n }\n\n public async downloadAndDecrypt(\n id: string,\n downloadRequest: DownloadRequest,\n signature: Bytes,\n secretKey: Uint8Array,\n ): Promise<{ share: Buffer | undefined; status: string }> {\n const { status, body: encryptedShare } = await this.sendDownload(\n id,\n downloadRequest,\n signature,\n );\n if (encryptedShare === undefined) {\n return { share: undefined, status };\n }\n const encryptedBuffer = ethers.getBytes(encryptedShare.encrypted_share);\n const publicKeyBuffer = ethers.getBytes(encryptedShare.public_key);\n const nonceBuffer = ethers.getBytes(encryptedShare.nonce);\n const open = nacl.box.open(encryptedBuffer, nonceBuffer, publicKeyBuffer, secretKey);\n if (open == null) {\n return { share: undefined, status: \"box-open-error\" };\n }\n // Remove blinding\n return { share: Buffer.from(open.subarray(32)), status };\n }\n\n public async sendUpdate(\n id: string,\n updateRequest: UpdateWalletsRequest,\n signature: string,\n ): Promise<string> {\n const authHeader: RequestInit[\"headers\"] = {\n Authorization: `eip712 ${signature}`,\n };\n\n const url = `${this.baseUrl}/offchain/${this.contractAddress}/shares/${id}`;\n const ok = await patchRequest(url, updateRequest, authHeader);\n\n if (!ok) {\n throw new Error(`Error updating wallets to ${this.contractAddress} at ${url}`);\n }\n\n return ok;\n }\n\n public async sendAddAddress(\n id: string,\n addRequest: AddAddressRequest,\n signature: string,\n ): Promise<string> {\n const authHeader = this.getAuthHeader(signature);\n const url = `${this.baseUrl}/offchain/${this.contractAddress}/shares/${id}/add_address`;\n const status = await patchRequest(url, addRequest, authHeader);\n if (status !== \"200\") {\n throw new Error(`Error adding a wallet to ${id} at ${url}`);\n }\n\n return status;\n }\n\n public async sendRemoveAddress(\n id: string,\n removeRequest: RemoveAddressRequest,\n signature: string,\n ): Promise<string> {\n const authHeader = this.getAuthHeader(signature);\n const url = `${this.baseUrl}/offchain/${this.contractAddress}/shares/${id}/remove_address`;\n const status = await patchRequest(url, removeRequest, authHeader);\n if (status !== \"200\") {\n throw new Error(`Error removing address from ${id} at ${url}`);\n }\n\n return status;\n }\n}\n","// This file is auto-generated from an abi-file using AbiCodegen.\n/* eslint-disable */\n// @ts-nocheck\n// noinspection ES6UnusedImports\nimport {\n AbiByteInput,\n AbiByteOutput,\n type AbiInput,\n type AbiOutput,\n type BlockchainAddress,\n type BlockchainStateClient,\n type StateWithClient,\n} from \"@partisiablockchain/abi-client\";\n\ntype Option<K> = K | undefined;\nexport class IdosContract {\n private readonly _client: BlockchainStateClient | undefined;\n private readonly _address: BlockchainAddress | undefined;\n\n public constructor(\n client: BlockchainStateClient | undefined,\n address: BlockchainAddress | undefined,\n ) {\n this._address = address;\n this._client = client;\n }\n public deserializeContractState(_input: AbiInput): ContractState {\n const nodes_vecLength = _input.readI32();\n const nodes: NodeConfig[] = [];\n for (let nodes_i = 0; nodes_i < nodes_vecLength; nodes_i++) {\n const nodes_elem: NodeConfig = this.deserializeNodeConfig(_input);\n nodes.push(nodes_elem);\n }\n return { nodes };\n }\n public deserializeNodeConfig(_input: AbiInput): NodeConfig {\n const address: BlockchainAddress = _input.readAddress();\n const endpoint: string = _input.readString();\n return { address, endpoint };\n }\n public async getState(): Promise<ContractState> {\n const bytes = await this._client?.getContractStateBinary(this._address!);\n if (bytes === undefined) {\n throw new Error(\"Unable to get state bytes\");\n }\n const input = AbiByteInput.createLittleEndian(bytes);\n return this.deserializeContractState(input);\n }\n}\nexport interface ContractState {\n nodes: NodeConfig[];\n}\n\nexport interface NodeConfig {\n address: BlockchainAddress;\n endpoint: string;\n}\nfunction serializeNodeConfig(_out: AbiOutput, _value: NodeConfig): void {\n const { address, endpoint } = _value;\n _out.writeAddress(address);\n _out.writeString(endpoint);\n}\n\nexport function initialize(nodes: NodeConfig[]): Buffer {\n return AbiByteOutput.serializeBigEndian((_out) => {\n _out.writeBytes(Buffer.from(\"ffffffff0f\", \"hex\"));\n _out.writeI32(nodes.length);\n for (const nodes_vec of nodes) {\n serializeNodeConfig(_out, nodes_vec);\n }\n });\n}\n\nexport function deserializeState(state: StateWithClient): ContractState;\nexport function deserializeState(bytes: Buffer): ContractState;\nexport function deserializeState(\n bytes: Buffer,\n client: BlockchainStateClient,\n address: BlockchainAddress,\n): ContractState;\nexport function deserializeState(\n state: Buffer | StateWithClient,\n client?: BlockchainStateClient,\n address?: BlockchainAddress,\n): ContractState {\n if (Buffer.isBuffer(state)) {\n const input = AbiByteInput.createLittleEndian(state);\n return new IdosContract(client, address).deserializeContractState(input);\n }\n const input = AbiByteInput.createLittleEndian(state.bytes);\n return new IdosContract(state.client, state.address).deserializeContractState(input);\n}\n","import type { FiniteFieldElement } from \"./finite-field-element\";\n\n/**\n * Polynomials with coefficients in a finite field.\n *\n * <p>Copied from <a href=\"https://gitlab.com/partisiablockchain/language/abi/zk-client\"> zk-client</a>.\n */\nexport class Polynomial<T extends FiniteFieldElement<T>> {\n private readonly coefficients: T[];\n\n private constructor(coefficients: T[]) {\n this.coefficients = coefficients;\n }\n\n /**\n * Construct a polynomial from a set of coefficients. The degree of the resultant polynomial is\n * assumed to be equal to the number of coefficients minus 1. The constant term of the polynomial\n * is assumed to be stored in the first position of the coefficients.\n *\n * @param coefficients the coefficients of the polynomial\n * @param zero zero element of the field\n * @return the constructed polynomial\n */\n static create<T extends FiniteFieldElement<T>>(coefficients: T[], zero: T): Polynomial<T> {\n return new Polynomial<T>(Polynomial.filterHighZeroes(coefficients, zero));\n }\n\n private static filterHighZeroes<T extends FiniteFieldElement<T>>(\n coefficients: T[],\n zero: T,\n ): T[] {\n for (let i = coefficients.length - 1; i >= 0; i--) {\n if (!coefficients[i].isZero()) {\n return coefficients.slice(0, i + 1);\n }\n }\n return [zero];\n }\n\n /**\n * Returns the coefficients of the polynomial.\n *\n * @return the coefficients of the polynomial\n */\n getCoefficients(): T[] {\n return this.coefficients.slice();\n }\n\n /**\n * Returns the degree of this polynomial.\n *\n * @return the degree of the polynomial\n */\n degree(): number {\n return this.coefficients.length - 1;\n }\n\n /**\n * Returns the constant term of the polynomial.\n *\n * @return the term stored on position 0 of the coefficients of this polynomial\n */\n getConstantTerm(): T {\n return this.coefficients[0];\n }\n\n /**\n * Evaluates this polynomial on a point. That is, if F is the polynomial and x a value, then this\n * method returns F(x).\n *\n * @param point the point to evaluate this polynomial on\n * @return F(point) where F is this polynomial\n */\n evaluate(point: T): T {\n const degree = this.degree();\n\n let result = this.coefficients[degree];\n for (let i = degree - 1; i >= 0; --i) {\n const current = this.coefficients[i];\n result = current.add(point.multiply(result));\n }\n return result;\n }\n}\n","import type { FiniteFieldElement } from \"./finite-field-element\";\nimport { Polynomial } from \"./polynomial\";\n\n/** Represents an element in GF(2^8) using the reduction polynomial x^8+x^4+x^3+x+1. */\nexport class F256 implements FiniteFieldElement<F256> {\n readonly value: number;\n\n private constructor(value: number) {\n this.value = value;\n }\n\n /**\n * The zero element.\n */\n static readonly ZERO: F256 = F256.createElement(0);\n\n /**\n * The one element.\n */\n static readonly ONE: F256 = F256.createElement(1);\n\n /**\n * Create a new field element with the given value.\n * @param value the value\n */\n static createElement(value: number): F256 {\n return new F256(value & 0xff);\n }\n\n /**\n * Get the computation alphas for this field.\n * @returns the computation alphas\n */\n static alphas(numNodes: number): readonly F256[] {\n return Array.from({ length: numNodes }, (_value, key) => F256.createElement(key + 1));\n }\n\n /**\n * Create a polynomial.\n * @param coefficients the coefficients of the polynomial\n */\n static createPoly(coefficients: F256[]): Polynomial<F256> {\n return Polynomial.create(coefficients, F256.ZERO);\n }\n\n /** @inheritDoc */\n add(other: F256): F256 {\n return Constants.elements[this.value ^ other.value];\n }\n\n /** @inheritDoc */\n isEqualTo(other: F256): boolean {\n return this.value === other.value;\n }\n\n /** @inheritDoc */\n isOne(): boolean {\n return this.value === 1;\n }\n\n /** @inheritDoc */\n isZero(): boolean {\n return this.value === 0;\n }\n\n /** @inheritDoc */\n modInverse(): F256 {\n return Constants.elements[Constants.multiplicativeInverse[this.value]];\n }\n\n /** @inheritDoc */\n multiply(other: F256): F256 {\n let a = this.value;\n let b = other.value;\n let m;\n let p = 0;\n for (let i = 0; i < 8; i++) {\n p = (p ^ (-(b & 1) & a)) & 0xff;\n m = -((a >> 7) & 1) & 0xff;\n a = ((a << 1) ^ (0b100011011 & m)) & 0xff;\n b = b >> 1;\n }\n return Constants.elements[p];\n }\n\n /** @inheritDoc */\n negate(): F256 {\n return this;\n }\n\n /** @inheritDoc */\n squareRoot(): F256 {\n throw new Error(\"Not implemented\");\n }\n\n /** @inheritDoc */\n subtract(other: F256): F256 {\n return this.add(other);\n }\n}\n\nconst Constants = {\n elements: Array.from({ length: 256 }, (_value, key) => F256.createElement(key)),\n multiplicativeInverse: [\n 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0, 0xb0, 0xe1, 0xe5, 0xc7,\n 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f, 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2,\n 0x3a, 0x6e, 0x5a, 0xf1, 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,\n 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f, 0x77, 0xbb, 0x59, 0x19,\n 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69, 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09,\n 0xed, 0x5c, 0x05, 0xca, 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,\n 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf, 0x33, 0x93, 0x21, 0x3b,\n 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c, 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82,\n 0x83, 0x7e, 0x7f, 0x80, 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,\n 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88, 0xf9, 0xdc, 0x89, 0x9a,\n 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48, 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62,\n 0x0c, 0xe0, 0x1f, 0xef, 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,\n 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04, 0x1b, 0xfc, 0xac, 0xe6,\n 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea, 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b,\n 0xb1, 0x0d, 0xd6, 0xeb, 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,\n 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0, 0xcd, 0x1a, 0x41, 0x1c,\n ],\n} as const;\n","import type { FiniteFieldElement } from \"./finite-field-element\";\nimport { Polynomial } from \"./polynomial\";\n\n// File copied from <a href=\"https://gitlab.com/partisiablockchain/language/abi/zk-client\"> zk-client</a>.\n\n/**\n * Try to interpolate a polynomial that passes through the supplied points.\n *\n * @param xs x-coordinates in the points\n * @param ys y-coordinates in the points\n * @param zero 0 element in the Finite Field.\n * @param one 1 element in the Finite Field.\n *\n * @returns the interpolated polynomial or null if unable to interpolate\n */\nfunction interpolate<T extends FiniteFieldElement<T>>(\n xs: readonly T[],\n ys: T[],\n zero: T,\n one: T,\n): Polynomial<T> {\n if (xs.length !== ys.length) {\n throw new Error(\"xs and ys must be of same size\");\n }\n\n if (xs.length === 0) {\n throw new Error(\"xs and ys must have at least one element\");\n }\n\n const n = xs.length;\n const c: T[] = Array(n).fill(one);\n c[0] = one;\n\n for (let i = 0; i < n; i++) {\n for (let j = i; j > 0; j--) {\n c[j] = c[j - 1].subtract(c[j].multiply(xs[i]));\n }\n c[0] = c[0].multiply(xs[i].negate());\n }\n\n const coefficients: T[] = Array(n).fill(zero);\n // Stryker disable next-line ArrayDeclaration\n const tc: T[] = Array(n).fill(zero);\n tc[n - 1] = one;\n for (let i = 0; i < n; i++) {\n let denominator = one;\n for (let j = 0; j < n; j++) {\n if (i !== j) {\n denominator = denominator.multiply(xs[i].subtract(xs[j]));\n }\n }\n\n const t: T = ys[i].multiply(denominator.modInverse());\n coefficients[n - 1] = coefficients[n - 1].add(t.multiply(tc[n - 1]));\n\n for (let j = n - 2; j >= 0; j--) {\n tc[j] = c[j + 1].add(tc[j + 1].multiply(xs[i]));\n coefficients[j] = coefficients[j].add(t.multiply(tc[j]));\n }\n }\n\n return Polynomial.create(coefficients, zero);\n}\n\n/**\n * Interpolate the minimal polynomial that passes through all the supplied points. And verify that\n * the polynomial has a degree less that maximalDegree.\n *\n * @param xs x-coordinates in the points\n * @param ys y-coordinates in the points\n * @param zero 0 element in the Finite Field.\n * @param one 1 element in the Finite Field.\n * @param maximalDegree the expected maximal degree\n * @return the interpolated polynomial\n */\nfunction interpolateCheckDegree<T extends FiniteFieldElement<T>>(\n xs: readonly T[],\n ys: T[],\n maximalDegree: number,\n zero: T,\n one: T,\n): Polynomial<T> {\n const poly = interpolate(xs, ys, zero, one);\n if (poly.degree() > maximalDegree) {\n throw new Error(\n `Interpolated polynomial has too high degree. Expected maximal=${maximalDegree}, actual=${poly.degree()}`,\n );\n }\n return poly;\n}\n\n/**\n * Try to interpolate a polynomial that passes through at least <code>2 &sdot; maximalDegree + 1\n * </code> of the supplied points.\n *\n * <p>Element lists ({@code xs} and {@code ys}) must have same size.\n *\n * @param xs x-coordinates in the points\n * @param ys y-coordinates in the points\n * @param maximalDegree the expected maximal degree\n * @param zero 0 element in the Finite Field.\n * @param one 1 element in the Finite Field.\n *\n * @returns the interpolated polynomial or undefined if unable to interpolate\n */\nfunction interpolateIfPossible<T extends FiniteFieldElement<T>>(\n xs: readonly T[],\n ys: T[],\n maximalDegree: number,\n zero: T,\n one: T,\n): Polynomial<T> | undefined {\n if (xs.length !== ys.length) {\n throw new Error(\"xs and ys must be of same size\");\n }\n return interpolateIfPossibleInner(xs, ys, maximalDegree, zero, one);\n}\n\nfunction interpolateIfPossibleInner<T extends FiniteFieldElement<T>>(\n xs: readonly T[],\n ys: T[],\n maximalDegree: number,\n zero: T,\n one: T,\n): Polynomial<T> | undefined {\n if (xs.length <= 2 * maximalDegree + 1) {\n const interpolated = interpolate(xs, ys, zero, one);\n if (interpolated.degree() > maximalDegree) {\n return undefined;\n }\n return interpolated;\n }\n for (let removeIndex = 0; removeIndex < xs.length; removeIndex++) {\n const interpolated = interpolateIfPossibleInner(\n withoutIndex(xs, removeIndex),\n withoutIndex(ys, removeIndex),\n maximalDegree,\n zero,\n one,\n );\n if (interpolated !== undefined) {\n return interpolated;\n }\n }\n return undefined;\n}\n\nfunction withoutIndex<T>(values: readonly T[], removeIndex: number): T[] {\n return values.filter((_value, index, _array) => index != removeIndex);\n}\n\n/**\n * Utility for lagrange interpolation.\n */\nexport const Lagrange: {\n interpolate: typeof interpolate;\n interpolateCheckDegree: typeof interpolateCheckDegree;\n interpolateIfPossible: typeof interpolateIfPossible;\n} = {\n interpolate,\n interpolateCheckDegree,\n interpolateIfPossible,\n};\n","import { randomBytes } from \"crypto\";\nimport { F256 } from \"./f256\";\nimport { Lagrange } from \"./lagrange\";\nimport type { SecretShareFactory } from \"./secret-share-factory\";\nimport type { SecretShares } from \"./secret-shares\";\n\n/**\n * Configuration for creating and reconstructing shamir secret shares.\n *\n * <p>The <code>numToReconstruct</code> value must be at least <code>numMalicious + 1</code> to be able\n * to reconstruct.\n *\n * <p>If <code>numToReconstruct</code> is less than <code>2 * numMalicious + 1</code> then there must be\n * some other way to guarantee that the shares are correct, e.g. through commitments on-chain.\n */\nexport interface ShamirConfig {\n /** Maximum number of malicious nodes. Depends on the threat model. */\n numMalicious: number;\n /** Total number of nodes to receive a share. */\n numNodes: number;\n /** Minimum number of shares needed to reconstruct a secret. */\n numToReconstruct: number;\n}\n\n/** Factory for creating elements of {@link ShamirSecretShares}. */\nexport class ShamirFactory implements SecretShareFactory<ShamirSecretShares> {\n private readonly shamirConfig: ShamirConfig;\n\n /**\n * Create the {@link ShamirFactory}.\n *\n * @param shamirConfig configuration for creating and reconstructing shamir secret shares.\n */\n constructor(shamirConfig: ShamirConfig) {\n this.shamirConfig = shamirConfig;\n }\n\n fromPlainText(numNodes: number, plainText: Buffer): ShamirSecretShares {\n if (numNodes != this.shamirConfig.numNodes) {\n throw new Error(\n `This shamir factory expects there to be ${this.shamirConfig.numNodes} nodes, but there was ${numNodes}.`,\n );\n }\n const randomElements = randomBytes(plainText.length * this.shamirConfig.numMalicious);\n const alphas = F256.alphas(this.shamirConfig.numNodes);\n const shares: F256[][] = Array.from({ length: this.shamirConfig.numNodes }, () => []);\n for (let i = 0; i < plainText.length; i++) {\n const coefficients = [F256.createElement(plainText[i])];\n for (let j = 0; j < this.shamirConfig.numMalicious; j++) {\n coefficients.push(\n F256.createElement(randomElements[this.shamirConfig.numMalicious * i + j]),\n );\n }\n const poly = F256.createPoly(coefficients);\n for (let j = 0; j < this.shamirConfig.numNodes; j++) {\n shares[j].push(poly.evaluate(alphas[j]));\n }\n }\n\n return new ShamirSecretShares(this.shamirConfig, shares);\n }\n\n fromSharesBytes(shares: Array<Buffer | undefined>): ShamirSecretShares {\n const elementShares = shares.map((bytes) => {\n if (bytes == undefined) {\n return undefined;\n }\n const elements = [];\n for (let i = 0; i < bytes.length; i++) {\n elements.push(F256.createElement(bytes[i]));\n }\n return elements;\n });\n return new ShamirSecretShares(this.shamirConfig, elementShares);\n }\n}\n\n/**\n * Secure secret-sharing scheme based on shamir-secret sharing.\n *\n * <p>Supported number of shares ({@code N}): {@code 4}\n *\n * <p>Based on the java implementation of the secret-sharing client.\n *\n * @see <a href=\"https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing\">Shamir's secret sharing,\n * Wikipedia</a>\n */\nexport class ShamirSecretShares implements SecretShares {\n private readonly shares: Array<F256[] | undefined>;\n private readonly shamirConfig: ShamirConfig;\n\n constructor(shamirConfig: ShamirConfig, shares: Array<F256[] | undefined>) {\n if (shares.length != shamirConfig.numNodes) {\n throw new Error(`There must be ${shamirConfig.numNodes} nodes`);\n }\n const numReceivedShares = shares.filter((s) => s != undefined).length;\n if (numReceivedShares < shamirConfig.numToReconstruct) {\n throw new Error(\n `Must have received at least ${shamirConfig.numToReconstruct} shares to reconstruct. Received ${numReceivedShares}.`,\n );\n }\n this.shamirConfig = shamirConfig;\n this.shares = shares;\n }\n\n getShareBytes(nodeIndex: number): Buffer {\n const share = this.shares[nodeIndex];\n if (share == undefined) {\n throw new Error(\"Expected share to be defined\");\n }\n return Buffer.from(share.map((field) => field.value));\n }\n\n numShares(): number {\n return this.shamirConfig.numNodes;\n }\n\n reconstructPlainText(): Buffer {\n const alphas = F256.alphas(this.shamirConfig.numNodes);\n const definedAlphas: F256[] = [];\n const definedShares: F256[][] = [];\n for (let i = 0; i < this.shares.length; i++) {\n const share = this.shares[i];\n if (share != undefined) {\n definedAlphas.push(alphas[i]);\n definedShares.push(share);\n }\n }\n\n const reconstructedElements = [];\n const numElements = definedShares[0].length;\n for (let i = 0; i < numElements; i++) {\n const sharesOfIthElement = [];\n for (let j = 0; j < definedShares.length; j++) {\n sharesOfIthElement.push(definedShares[j][i]);\n }\n const interpolated = Lagrange.interpolateIfPossible(\n definedAlphas,\n sharesOfIthElement,\n this.shamirConfig.numMalicious,\n F256.ZERO,\n F256.ONE,\n );\n if (interpolated === undefined) {\n throw new Error(\"Unable to reconstruct secret\");\n }\n reconstructedElements.push(interpolated.getConstantTerm().value);\n }\n return Buffer.from(reconstructedElements);\n }\n\n public static readonly FACTORY: SecretShareFactory<ShamirSecretShares> = new ShamirFactory({\n numMalicious: 1,\n numNodes: 4,\n numToReconstruct: 2,\n });\n}\n\nexport function getRandomBytes(length: number): Buffer {\n const array = new Uint8Array(length);\n crypto.getRandomValues(array);\n\n return Buffer.from(array);\n}\n","import type { TypedDataDomain, TypedDataField } from \"ethers\";\n\nexport type PbcAddress = string;\nexport type Bytes32 = string;\nexport type Bytes24 = string;\nexport type Address = string;\nexport type Bytes = string;\n\nexport const UPLOAD_TYPES: Record<string, TypedDataField[]> = {\n UploadSignatureMessage: [\n { name: \"share_commitments\", type: \"bytes32[]\" },\n { name: \"recovering_addresses\", type: \"string[]\" },\n ],\n};\n\nexport const DOWNLOAD_TYPES: Record<string, TypedDataField[]> = {\n DownloadSignatureMessage: [\n { name: \"recovering_address\", type: \"string\" },\n { name: \"timestamp\", type: \"uint64\" },\n { name: \"public_key\", type: \"bytes32\" },\n ],\n};\n\nexport const UPDATE_TYPES: Record<string, TypedDataField[]> = {\n UpdateWalletsSignatureMessage: [\n { name: \"recovering_addresses\", type: \"string[]\" },\n { name: \"timestamp\", type: \"uint64\" },\n ],\n};\n\nexport const ADD_ADDRESS_TYPES: Record<string, TypedDataField[]> = {\n AddAddressSignatureMessage: [\n { name: \"recovering_address\", type: \"string\" },\n { name: \"address_to_add\", type: \"string\" },\n { name: \"timestamp\", type: \"uint64\" },\n ],\n};\n\nexport const REMOVE_ADDRESS_TYPES: Record<string, TypedDataField[]> = {\n RemoveAddressSignatureMessage: [\n { name: \"recovering_address\", type: \"string\" },\n { name: \"address_to_remove\", type: \"string\" },\n { name: \"timestamp\", type: \"uint64\" },\n ],\n};\n\nexport interface UploadSignatureMessage {\n share_commitments: Bytes32[];\n recovering_addresses: Address[];\n}\n\nexport interface Sharing {\n share_commitments: Bytes32[];\n recovering_addresses: Address[];\n share_data: Bytes;\n}\n\nexport interface DownloadSignatureMessage {\n recovering_address: Address;\n timestamp: number;\n public_key: Bytes32;\n}\n\nexport type DownloadRequest = DownloadSignatureMessage;\n\nexport interface AddAddressSignatureMessage {\n recovering_address: Address;\n address_to_add: Address;\n timestamp: number;\n}\n\nexport type AddAddressRequest = AddAddressSignatureMessage;\n\nexport interface RemoveAddressSignatureMessage {\n recovering_address: Address;\n address_to_remove: Address;\n timestamp: number;\n}\n\nexport type RemoveAddressRequest = RemoveAddressSignatureMessage;\n\nexport interface UpdateWalletsSignatureMessage {\n recovering_addresses: Address[];\n timestamp: number;\n}\n\nexport type UpdateWalletsRequest = UpdateWalletsSignatureMessage;\n\nexport interface EncryptedShare {\n encrypted_share: Bytes;\n public_key: Bytes32;\n nonce: Bytes24;\n}\n\nexport type DownloadMessageToSign = {\n domain: TypedDataDomain;\n types: Record<string, TypedDataField[]>;\n value: DownloadSignatureMessage;\n};\n\nexport type UploadMessageToSign = {\n domain: TypedDataDomain;\n types: Record<string, TypedDataField[]>;\n value: UploadSignatureMessage;\n};\n\nexport type AddAddressMessageToSign = {\n domain: TypedDataDomain;\n types: Record<string, TypedDataField[]>;\n value: AddAddressSignatureMessage;\n};\n\nexport type RemoveAddressMessageToSign = {\n domain: TypedDataDomain;\n types: Record<string, TypedDataField[]>;\n value: RemoveAddressSignatureMessage;\n};\n","import { WALLET_TYPES, type WalletType } from \"@idos-network/kwil-infra/actions\";\nimport {\n ChainControllerApi,\n Configuration,\n} from \"@partisiablockchain/blockchain-api-transaction-client\";\nimport { ethers, type TypedDataDomain } from \"ethers\";\nimport { EngineClient } from \"./engine-client\";\nimport { deserializeState } from \"./generated/IdosContract\";\nimport { getRandomBytes, ShamirFactory } from \"./secretsharing/shamir-secret-shares\";\nimport {\n ADD_ADDRESS_TYPES,\n type AddAddressMessageToSign,\n type AddAddressSignatureMessage,\n type Bytes,\n DOWNLOAD_TYPES,\n type DownloadMessageToSign,\n type DownloadSignatureMessage,\n type PbcAddress,\n REMOVE_ADDRESS_TYPES,\n type RemoveAddressMessageToSign,\n type RemoveAddressSignatureMessage,\n type Sharing,\n UPLOAD_TYPES,\n type UploadMessageToSign,\n type UploadSignatureMessage,\n} from \"./types\";\nimport invariant from \"tiny-invariant\";\n\nexport class Client {\n private readonly baseUrl: string;\n private readonly contractAddress: PbcAddress;\n private engines: EngineClient[] | undefined;\n private walletType!: WalletType;\n private signerAddress!: string;\n private signerPublicKey: string | undefined;\n private factory: ShamirFactory;\n private numNodes: number;\n\n constructor(\n baseUrl: string,\n contractAddress: PbcAddress,\n numMalicious: number,\n numNodes: number,\n numToReconstruct: number,\n walletType: WalletType,\n signerAddress: string,\n signerPublicKey?: string,\n ) {\n this.baseUrl = baseUrl;\n this.contractAddress = contractAddress;\n\n this.reconfigure(walletType, signerAddress, signerPublicKey);\n \n this.numNodes = numNodes;\n // TODO: Make these configurable from env variables\n this.factory = new ShamirFactory({ numMalicious, numNodes, numToReconstruct });\n }\n\n public reconfigure(\n walletType: WalletType,\n signerAddress: string,\n signerPublicKey?: string,\n ): void {\n // @deprecated\n // Remove this method after a while\n if ([\"evm\", \"xrpl\", \"near\", \"facesign\", \"stellar\"].includes(walletType as string)) {\n console.warn(\"Deprecated wallet type\", walletType, \", please upgrade to latest SDK version\");\n switch (walletType as string) {\n case \"evm\":\n walletType = \"EVM\";\n break;\n case \"xrpl\":\n walletType = \"XRPL\";\n break;\n case \"near\":\n walletType = \"NEAR\";\n break;\n case \"stellar\":\n walletType = \"Stellar\";\n break;\n case \"facesign\":\n walletType = \"FaceSign\";\n break;\n }\n }\n \n invariant(WALLET_TYPES.includes(walletType), `Invalid signer type: ${walletType}`);\n invariant(\n // XRPL, NEAR and FaceSign require a public key, EVM does not\n ([\"XRPL\", \"NEAR\", \"FaceSign\"].includes(walletType) && signerPublicKey) || walletType === \"EVM\",\n \"Signer public key is required for XRPL, NEAR and FaceSign\",\n );\n\n this.walletType = walletType;\n // Reset engines to force re-creation of them since they are using old signer information\n this.engines = undefined;\n this.signerAddress = signerAddress;\n if (signerPublicKey) this.signerPublicKey = signerPublicKey;\n }\n\n public async uploadSecret(\n id: string,\n uploadSignature: UploadSignatureMessage,\n signature: Bytes,\n blindedShares: Buffer[],\n ): Promise<{ status: string }> {\n const engineClients = await this.getEngines();\n const promises = [];\n for (let i = 0; i < engineClients.length; i++) {\n const engineClient = engineClients[i];\n const uploadRequest: Sharing = {\n ...uploadSignature,\n share_data: ethers.hexlify(blindedShares[i]),\n };\n promises.push(engineClient.sendUpload(id, uploadRequest, signature));\n }\n const statuses = await Promise.all(promises);\n\n if (statuses.every((item) => item === \"201\")) {\n return { status: \"success\" };\n }\n\n if (statuses.filter((item) => item === \"201\").length > 0) {\n return { status: \"partial-success\" };\n }\n\n return { status: \"failure\" };\n }\n\n public getBlindedShares(secret: Buffer): Buffer[] {\n // TODO: Make the number of nodes configurable from env variables\n const secretShares = this.factory.fromPlainText(this.numNodes, secret);\n var blindedShares: Buffer[] = [];\n for (let i = 0; i < secretShares.numShares(); i++) {\n blindedShares.push(Client.blindShare(secretShares.getShareBytes(i)));\n }\n return blindedShares;\n }\n\n public uploadMessageToSign(uploadRequest: UploadSignatureMessage): UploadMessageToSign {\n return {\n domain: this.getTypedDomain(),\n types: UPLOAD_TYPES,\n value: uploadRequest,\n };\n }\n\n public uploadRequest(blindedShares: Buffer[]): UploadSignatureMessage {\n console.log({ mpc: \"uploading to MPC\", walletType: this.walletType, address: this.signerAddress, publicKey: this.signerPublicKey });\n\n var address = \"\";\n switch (this.walletType) {\n case \"EVM\":\n address = `eip712:${this.signerAddress}`;\n break;\n case \"XRPL\":\n address = `XRPL:${this.signerPublicKey}`;\n break;\n case \"NEAR\":\n address = `NEAR:${this.signerPublicKey?.replace(\"ed25519:\", \"\")}`;\n break;\n case \"FaceSign\":\n address = `FACESIGN:${this.signerPublicKey}`;\n break;\n default:\n throw new Error(\"Invalid signer type\");\n }\n return {\n share_commitments: blindedShares.map((b) => ethers.keccak256(b)),\n recovering_addresses: [address],\n };\n }\n\n public downloadMessageToSign(downloadRequest: DownloadSignatureMessage): DownloadMessageToSign {\n return {\n domain: this.getTypedDomain(),\n types: DOWNLOAD_TYPES,\n value: downloadRequest,\n };\n }\n\n public downloadRequest(publicKey: Uint8Array): DownloadSignatureMessage {\n var address = \"\";\n switch (this.walletType) {\n case \"EVM\":\n address = `eip712:${this.signerAddress}`;\n break;\n case \"XRPL\":\n address = `XRPL:${this.signerPublicKey}`;\n break;\n case \"NEAR\":\n address = `NEAR:${this.signerPublicKey?.replace(\"ed25519:\", \"\")}`;\n break;\n case \"FaceSign\":\n address = `FACESIGN:${this.signerPublicKey}`;\n break;\n default:\n throw new Error(\"Invalid signer type\");\n }\n return {\n recovering_address: address,\n timestamp: Date.now(),\n public_key: ethers.hexlify(publicKey),\n };\n }\n\n public async downloadSecret(\n id: string,\n downloadRequest: DownloadSignatureMessage,\n signature: Bytes,\n secretKey: Uint8Array,\n ): Promise<{ status: string; secret: Buffer | undefined }> {\n const shares = [];\n const engineClients = await this.getEngines();\n for (let i = 0; i < engineClients.length; i++) {\n const engineClient = engineClients[i];\n shares.push(engineClient.downloadAndDecrypt(id, downloadRequest, signature, secretKey));\n }\n const secretShares = await Promise.all(shares);\n\n console.log({ secretSharesDownloadStatuses: secretShares.map((item) => item.status) });\n\n if (secretShares.every((item) => item.status === \"404\")) {\n return { status: \"not-stored\", secret: undefined };\n }\n\n var secret: Buffer;\n try {\n secret = this.factory\n .fromSharesBytes(secretShares.map((item) => item.share))\n .reconstructPlainText();\n return { status: \"ok\", secret };\n } catch (_e) {\n return { status: \"error\", secret: undefined };\n }\n }\n\n public addAddressMessageToSign(\n addressToAdd: string,\n publicKey: string | undefined,\n addressToAddType: string,\n ): AddAddressMessageToSign {\n var address = \"\";\n switch (this.walletType) {\n case \"EVM\":\n address = `eip712:${this.signerAddress}`;\n break;\n case \"XRPL\":\n address = `XRPL:${this.signerPublicKey}`;\n break;\n case \"NEAR\":\n address = `NEAR:${this.signerPublicKey?.replace(\"ed25519:\", \"\")}`;\n break;\n case \"FaceSign\":\n address = `FACESIGN:${this.signerPublicKey}`;\n break;\n default:\n throw new Error(\"Invalid signer type\");\n }\n\n var addressToAddFormatted = \"\";\n // @deprecated toLowerCase remove when we have updated the SDK\n switch (addressToAddType.toLowerCase()) {\n case \"evm\":\n addressToAddFormatted = `eip712:${addressToAdd}`;\n break;\n case \"xrpl\":\n addressToAddFormatted = `XRPL:${publicKey}`;\n break;\n case \"near\":\n addressToAddFormatted = `NEAR:${publicKey?.replace(\"ed25519:\", \"\")}`;\n break;\n case \"facesign\":\n addressToAddFormatted = `FACESIGN:${publicKey}`;\n break;\n default:\n throw new Error(\"Invalid address to add type\");\n }\n\n const value = {\n recovering_address: address,\n address_to_add: addressToAddFormatted,\n timestamp: Date.now(),\n };\n\n return {\n domain: this.getTypedDomain(),\n types: ADD_ADDRESS_TYPES,\n value,\n };\n }\n\n public removeAddressMessageToSign(\n addressToRemove: string,\n publicKey: string | undefined,\n addressToRemoveType: string,\n ): RemoveAddressMessageToSign {\n var address = \"\";\n switch (this.walletType) {\n case \"EVM\":\n address = `eip712:${this.signerAddress}`;\n break;\n case \"XRPL\":\n address = `XRPL:${this.signerPublicKey}`;\n break;\n case \"NEAR\":\n address = `NEAR:${this.signerPublicKey?.replace(\"ed25519:\", \"\")}`;\n break;\n case \"FaceSign\":\n address = `FACESIGN:${this.signerPublicKey}`;\n break;\n default:\n throw new Error(\"Invalid signer type\");\n }\n\n var addressToRemoveFormatted = \"\";\n // @deprecated toLowerCase remove when we have updated the SDK\n switch (addressToRemoveType.toLowerCase()) {\n case \"evm\":\n addressToRemoveFormatted = `eip712:${addressToRemove}`;\n break;\n case \"xrpl\":\n addressToRemoveFormatted = `XRPL:${publicKey}`;\n break;\n case \"near\":\n addressToRemoveFormatted = `NEAR:${publicKey?.replace(\"ed25519:\", \"\")}`;\n break;\n case \"facesign\":\n addressToRemoveFormatted = `FACESIGN:${publicKey}`;\n break;\n default:\n throw new Error(\"Invalid address to remove type\");\n }\n\n const value = {\n recovering_address: address,\n address_to_remove: addressToRemoveFormatted,\n timestamp: Date.now(),\n };\n return {\n domain: this.getTypedDomain(),\n types: REMOVE_ADDRESS_TYPES,\n value,\n };\n }\n\n public async addAddress(\n userId: string,\n message: AddAddressSignatureMessage,\n signature: string,\n ): Promise<string> {\n const engineClients = await this.getEngines();\n const promises = [];\n for (let i = 0; i < engineClients.length; i++) {\n const engineClient = engineClients[i];\n promises.push(engineClient.sendAddAddress(userId, message, signature));\n }\n const statuses = await Promise.all(promises);\n\n if (statuses.every((item) => item === \"200\")) {\n return \"success\";\n }\n\n return \"failure\";\n }\n\n public async removeAddress(\n userId: string,\n message: RemoveAddressSignatureMessage,\n signature: string,\n ): Promise<string> {\n const engineClients = await this.getEngines();\n const promises = [];\n for (let i = 0; i < engineClients.length; i++) {\n const engineClient = engineClients[i];\n promises.push(engineClient.sendRemoveAddress(userId, message, signature));\n }\n const statuses = await Promise.all(promises);\n\n if (statuses.every((item) => item === \"200\")) {\n return \"success\";\n }\n\n return \"failure\";\n }\n\n private getTypedDomain(): TypedDataDomain {\n return {\n name: \"idOS secret store contract\",\n version: \"1\",\n verifyingContract: `0x${this.contractAddress.substring(2)}`,\n };\n }\n\n private async getEngines(): Promise<EngineClient[]> {\n if (this.engines === undefined) {\n const chainController = new ChainControllerApi(new Configuration({ basePath: this.baseUrl }));\n const rawState = await chainController.getContract({ address: this.contractAddress });\n // oxlint-disable-next-line typescript/no-non-null-assertion -- we know serializedContract is present here\n const state = deserializeState(Buffer.from(rawState.serializedContract!, \"base64\"));\n this.engines = state.nodes.map(\n (value) => new EngineClient(value.endpoint, this.contractAddress, this.walletType),\n );\n }\n return this.engines;\n }\n\n private static blindShare(share: Buffer): Buffer {\n return Buffer.concat([getRandomBytes(32), share]);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client-rcvBXslm.mjs","names":[],"sources":["../src/mpc/api.ts","../src/mpc/engine-client.ts","../src/mpc/generated/IdosContract.ts","../src/mpc/secretsharing/polynomial.ts","../src/mpc/secretsharing/f256.ts","../src/mpc/secretsharing/lagrange.ts","../src/mpc/secretsharing/shamir-secret-shares.ts","../src/mpc/types.ts","../src/mpc/client.ts"],"sourcesContent":["const postHeaders = {\n Accept: \"application/json, text/plain, */*\",\n \"Content-Type\": \"application/json\",\n};\n\nconst getHeaders = {\n Accept: \"application/json, text/plain, */*\",\n};\n\nexport type RequestType = \"GET\" | \"PUT\" | \"POST\" | \"PATCH\";\n\nfunction buildOptions<T>(method: RequestType, headers: RequestInit[\"headers\"], entityBytes: T) {\n const result: RequestInit = { method, headers, body: null };\n\n if (entityBytes != null) {\n result.body = JSON.stringify(entityBytes);\n }\n return result;\n}\n\n/**\n * Make a http get-request.\n *\n * @param url the url to request.\n * @return a promise containing the result of the get request.\n */\nexport function getRequest<R>(url: string): Promise<{ status: string; body: R | undefined }> {\n const options = buildOptions(\"GET\", getHeaders, null);\n return handleFetch<R>(fetch(url, options));\n}\n\n/**\n * Make a http put-request.\n *\n * @param url the url to request.\n * @param object the object to put.\n * @param headers\n * @return a promise containing whether the put succeeded or not.\n */\nexport function putRequest<T>(\n url: string,\n object: T,\n headers?: Record<string, string>,\n): Promise<string> {\n const options = buildOptions(\"PUT\", { ...postHeaders, ...headers }, object);\n return fetch(url, options)\n .then(async (response) => {\n const responseClone = response.clone();\n const responseBody = await responseClone.text();\n console.log({ responseCode: response.status, responseBody });\n return response.status.toString();\n })\n .catch((error) => {\n console.error(error);\n return error;\n });\n}\n\n/**\n * Make a http patch-request.\n *\n * @param url the url to request.\n * @param object the object to put.\n * @param headers\n * @return a promise containing whether the put succeeded or not.\n */\nexport function patchRequest<T>(\n url: string,\n object: T,\n headers?: RequestInit[\"headers\"],\n): Promise<string> {\n const options = buildOptions(\"PATCH\", { ...postHeaders, ...headers }, object);\n return fetch(url, options)\n .then(async (response) => {\n const responseClone = response.clone();\n const responseBody = await responseClone.text();\n console.log({ responseCode: response.status, responseBody });\n return response.status.toString();\n })\n .catch((error) => {\n console.error(error);\n return error;\n });\n}\n\n/**\n * Make a http post-request.\n *\n * @param url the url to request.\n * @param object the object to post.\n * @param headers\n * @return a promise containing the result of the post request.\n */\nexport function postRequest<T, R>(\n url: string,\n object: T,\n headers?: Record<string, string>,\n): Promise<{ status: string; body: R | undefined }> {\n const options = buildOptions(\"POST\", { ...postHeaders, ...headers }, object);\n return handleFetch<R>(fetch(url, options));\n}\n\nfunction handleFetch<T>(\n promise: Promise<Response>,\n): Promise<{ status: string; body: T | undefined }> {\n return promise\n .then(async (response) => {\n const responseClone = response.clone();\n const responseBody = await responseClone.text();\n console.log({ responseCode: response.status, responseBody });\n\n if (response.status === 200) {\n const data = (await response.json()) as T;\n return { status: response.status.toString(), body: data };\n }\n return { status: response.status.toString(), body: undefined };\n })\n .catch((error) => {\n console.error(error);\n return { status: \"fetch-error\", body: undefined };\n });\n}\n","import type { WalletType } from \"@idos-network/kwil-infra/actions\";\nimport { ethers } from \"ethers\";\nimport nacl from \"tweetnacl\";\nimport { patchRequest, postRequest, putRequest } from \"./api\";\nimport type {\n AddAddressRequest,\n Bytes,\n DownloadRequest,\n EncryptedShare,\n PbcAddress,\n RemoveAddressRequest,\n Sharing,\n UpdateWalletsRequest,\n} from \"./types\";\n\nexport class EngineClient {\n private readonly baseUrl: string;\n private readonly contractAddress: PbcAddress;\n private readonly walletType: WalletType;\n\n constructor(baseUrl: string, contractAddress: PbcAddress, walletType: WalletType) {\n this.contractAddress = contractAddress;\n this.baseUrl = baseUrl;\n this.walletType = walletType;\n }\n\n private getAuthHeader(signature: string): Record<string, string> {\n let prefix: string;\n switch (this.walletType) {\n case \"EVM\":\n prefix = \"eip712\";\n break;\n case \"NEAR\":\n prefix = \"NEAR\";\n break;\n case \"XRPL\":\n prefix = \"XRPL\";\n break;\n case \"FaceSign\":\n prefix = \"FACESIGN\";\n break;\n default:\n prefix = \"eip712\"; // fallback to eip712 for unknown types\n }\n\n return {\n Authorization: `${prefix} ${signature}`,\n };\n }\n\n public async sendUpload(id: string, uploadRequest: Sharing, signature: Bytes): Promise<string> {\n const authHeader = this.getAuthHeader(signature);\n const url = `${this.baseUrl}/offchain/${this.contractAddress}/shares/${id}`;\n const status = await putRequest(url, uploadRequest, authHeader);\n if (status !== \"201\") {\n throw new Error(`Error uploading share to ${this.contractAddress} at ${url}`);\n }\n return status;\n }\n\n public async sendDownload(\n id: string,\n downloadRequest: DownloadRequest,\n signature: Bytes,\n ): Promise<{ status: string; body: EncryptedShare | undefined }> {\n const authHeader = this.getAuthHeader(signature);\n const url = `${this.baseUrl}/offchain/${this.contractAddress}/shares/${id}`;\n return await postRequest(url, downloadRequest, authHeader);\n }\n\n public async downloadAndDecrypt(\n id: string,\n downloadRequest: DownloadRequest,\n signature: Bytes,\n secretKey: Uint8Array,\n ): Promise<{ share: Buffer | undefined; status: string }> {\n const { status, body: encryptedShare } = await this.sendDownload(\n id,\n downloadRequest,\n signature,\n );\n if (encryptedShare === undefined) {\n return { share: undefined, status };\n }\n const encryptedBuffer = ethers.getBytes(encryptedShare.encrypted_share);\n const publicKeyBuffer = ethers.getBytes(encryptedShare.public_key);\n const nonceBuffer = ethers.getBytes(encryptedShare.nonce);\n const open = nacl.box.open(encryptedBuffer, nonceBuffer, publicKeyBuffer, secretKey);\n if (open == null) {\n return { share: undefined, status: \"box-open-error\" };\n }\n // Remove blinding\n return { share: Buffer.from(open.subarray(32)), status };\n }\n\n public async sendUpdate(\n id: string,\n updateRequest: UpdateWalletsRequest,\n signature: string,\n ): Promise<string> {\n const authHeader: RequestInit[\"headers\"] = {\n Authorization: `eip712 ${signature}`,\n };\n\n const url = `${this.baseUrl}/offchain/${this.contractAddress}/shares/${id}`;\n const ok = await patchRequest(url, updateRequest, authHeader);\n\n if (!ok) {\n throw new Error(`Error updating wallets to ${this.contractAddress} at ${url}`);\n }\n\n return ok;\n }\n\n public async sendAddAddress(\n id: string,\n addRequest: AddAddressRequest,\n signature: string,\n ): Promise<string> {\n const authHeader = this.getAuthHeader(signature);\n const url = `${this.baseUrl}/offchain/${this.contractAddress}/shares/${id}/add_address`;\n const status = await patchRequest(url, addRequest, authHeader);\n if (status !== \"200\") {\n throw new Error(`Error adding a wallet to ${id} at ${url}`);\n }\n\n return status;\n }\n\n public async sendRemoveAddress(\n id: string,\n removeRequest: RemoveAddressRequest,\n signature: string,\n ): Promise<string> {\n const authHeader = this.getAuthHeader(signature);\n const url = `${this.baseUrl}/offchain/${this.contractAddress}/shares/${id}/remove_address`;\n const status = await patchRequest(url, removeRequest, authHeader);\n if (status !== \"200\") {\n throw new Error(`Error removing address from ${id} at ${url}`);\n }\n\n return status;\n }\n}\n","// This file is auto-generated from an abi-file using AbiCodegen.\n/* eslint-disable */\n// @ts-nocheck\n// noinspection ES6UnusedImports\nimport {\n AbiByteInput,\n AbiByteOutput,\n type AbiInput,\n type AbiOutput,\n type BlockchainAddress,\n type BlockchainStateClient,\n type StateWithClient,\n} from \"@partisiablockchain/abi-client\";\n\ntype Option<K> = K | undefined;\nexport class IdosContract {\n private readonly _client: BlockchainStateClient | undefined;\n private readonly _address: BlockchainAddress | undefined;\n\n public constructor(\n client: BlockchainStateClient | undefined,\n address: BlockchainAddress | undefined,\n ) {\n this._address = address;\n this._client = client;\n }\n public deserializeContractState(_input: AbiInput): ContractState {\n const nodes_vecLength = _input.readI32();\n const nodes: NodeConfig[] = [];\n for (let nodes_i = 0; nodes_i < nodes_vecLength; nodes_i++) {\n const nodes_elem: NodeConfig = this.deserializeNodeConfig(_input);\n nodes.push(nodes_elem);\n }\n return { nodes };\n }\n public deserializeNodeConfig(_input: AbiInput): NodeConfig {\n const address: BlockchainAddress = _input.readAddress();\n const endpoint: string = _input.readString();\n return { address, endpoint };\n }\n public async getState(): Promise<ContractState> {\n const bytes = await this._client?.getContractStateBinary(this._address!);\n if (bytes === undefined) {\n throw new Error(\"Unable to get state bytes\");\n }\n const input = AbiByteInput.createLittleEndian(bytes);\n return this.deserializeContractState(input);\n }\n}\nexport interface ContractState {\n nodes: NodeConfig[];\n}\n\nexport interface NodeConfig {\n address: BlockchainAddress;\n endpoint: string;\n}\nfunction serializeNodeConfig(_out: AbiOutput, _value: NodeConfig): void {\n const { address, endpoint } = _value;\n _out.writeAddress(address);\n _out.writeString(endpoint);\n}\n\nexport function initialize(nodes: NodeConfig[]): Buffer {\n return AbiByteOutput.serializeBigEndian((_out) => {\n _out.writeBytes(Buffer.from(\"ffffffff0f\", \"hex\"));\n _out.writeI32(nodes.length);\n for (const nodes_vec of nodes) {\n serializeNodeConfig(_out, nodes_vec);\n }\n });\n}\n\nexport function deserializeState(state: StateWithClient): ContractState;\nexport function deserializeState(bytes: Buffer): ContractState;\nexport function deserializeState(\n bytes: Buffer,\n client: BlockchainStateClient,\n address: BlockchainAddress,\n): ContractState;\nexport function deserializeState(\n state: Buffer | StateWithClient,\n client?: BlockchainStateClient,\n address?: BlockchainAddress,\n): ContractState {\n if (Buffer.isBuffer(state)) {\n const input = AbiByteInput.createLittleEndian(state);\n return new IdosContract(client, address).deserializeContractState(input);\n }\n const input = AbiByteInput.createLittleEndian(state.bytes);\n return new IdosContract(state.client, state.address).deserializeContractState(input);\n}\n","import type { FiniteFieldElement } from \"./finite-field-element\";\n\n/**\n * Polynomials with coefficients in a finite field.\n *\n * <p>Copied from <a href=\"https://gitlab.com/partisiablockchain/language/abi/zk-client\"> zk-client</a>.\n */\nexport class Polynomial<T extends FiniteFieldElement<T>> {\n private readonly coefficients: T[];\n\n private constructor(coefficients: T[]) {\n this.coefficients = coefficients;\n }\n\n /**\n * Construct a polynomial from a set of coefficients. The degree of the resultant polynomial is\n * assumed to be equal to the number of coefficients minus 1. The constant term of the polynomial\n * is assumed to be stored in the first position of the coefficients.\n *\n * @param coefficients the coefficients of the polynomial\n * @param zero zero element of the field\n * @return the constructed polynomial\n */\n static create<T extends FiniteFieldElement<T>>(coefficients: T[], zero: T): Polynomial<T> {\n return new Polynomial<T>(Polynomial.filterHighZeroes(coefficients, zero));\n }\n\n private static filterHighZeroes<T extends FiniteFieldElement<T>>(\n coefficients: T[],\n zero: T,\n ): T[] {\n for (let i = coefficients.length - 1; i >= 0; i--) {\n if (!coefficients[i].isZero()) {\n return coefficients.slice(0, i + 1);\n }\n }\n return [zero];\n }\n\n /**\n * Returns the coefficients of the polynomial.\n *\n * @return the coefficients of the polynomial\n */\n getCoefficients(): T[] {\n return this.coefficients.slice();\n }\n\n /**\n * Returns the degree of this polynomial.\n *\n * @return the degree of the polynomial\n */\n degree(): number {\n return this.coefficients.length - 1;\n }\n\n /**\n * Returns the constant term of the polynomial.\n *\n * @return the term stored on position 0 of the coefficients of this polynomial\n */\n getConstantTerm(): T {\n return this.coefficients[0];\n }\n\n /**\n * Evaluates this polynomial on a point. That is, if F is the polynomial and x a value, then this\n * method returns F(x).\n *\n * @param point the point to evaluate this polynomial on\n * @return F(point) where F is this polynomial\n */\n evaluate(point: T): T {\n const degree = this.degree();\n\n let result = this.coefficients[degree];\n for (let i = degree - 1; i >= 0; --i) {\n const current = this.coefficients[i];\n result = current.add(point.multiply(result));\n }\n return result;\n }\n}\n","import type { FiniteFieldElement } from \"./finite-field-element\";\nimport { Polynomial } from \"./polynomial\";\n\n/** Represents an element in GF(2^8) using the reduction polynomial x^8+x^4+x^3+x+1. */\nexport class F256 implements FiniteFieldElement<F256> {\n readonly value: number;\n\n private constructor(value: number) {\n this.value = value;\n }\n\n /**\n * The zero element.\n */\n static readonly ZERO: F256 = F256.createElement(0);\n\n /**\n * The one element.\n */\n static readonly ONE: F256 = F256.createElement(1);\n\n /**\n * Create a new field element with the given value.\n * @param value the value\n */\n static createElement(value: number): F256 {\n return new F256(value & 0xff);\n }\n\n /**\n * Get the computation alphas for this field.\n * @returns the computation alphas\n */\n static alphas(numNodes: number): readonly F256[] {\n return Array.from({ length: numNodes }, (_value, key) => F256.createElement(key + 1));\n }\n\n /**\n * Create a polynomial.\n * @param coefficients the coefficients of the polynomial\n */\n static createPoly(coefficients: F256[]): Polynomial<F256> {\n return Polynomial.create(coefficients, F256.ZERO);\n }\n\n /** @inheritDoc */\n add(other: F256): F256 {\n return Constants.elements[this.value ^ other.value];\n }\n\n /** @inheritDoc */\n isEqualTo(other: F256): boolean {\n return this.value === other.value;\n }\n\n /** @inheritDoc */\n isOne(): boolean {\n return this.value === 1;\n }\n\n /** @inheritDoc */\n isZero(): boolean {\n return this.value === 0;\n }\n\n /** @inheritDoc */\n modInverse(): F256 {\n return Constants.elements[Constants.multiplicativeInverse[this.value]];\n }\n\n /** @inheritDoc */\n multiply(other: F256): F256 {\n let a = this.value;\n let b = other.value;\n let m;\n let p = 0;\n for (let i = 0; i < 8; i++) {\n p = (p ^ (-(b & 1) & a)) & 0xff;\n m = -((a >> 7) & 1) & 0xff;\n a = ((a << 1) ^ (0b100011011 & m)) & 0xff;\n b = b >> 1;\n }\n return Constants.elements[p];\n }\n\n /** @inheritDoc */\n negate(): F256 {\n return this;\n }\n\n /** @inheritDoc */\n squareRoot(): F256 {\n throw new Error(\"Not implemented\");\n }\n\n /** @inheritDoc */\n subtract(other: F256): F256 {\n return this.add(other);\n }\n}\n\nconst Constants = {\n elements: Array.from({ length: 256 }, (_value, key) => F256.createElement(key)),\n multiplicativeInverse: [\n 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0, 0xb0, 0xe1, 0xe5, 0xc7,\n 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f, 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2,\n 0x3a, 0x6e, 0x5a, 0xf1, 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,\n 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f, 0x77, 0xbb, 0x59, 0x19,\n 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69, 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09,\n 0xed, 0x5c, 0x05, 0xca, 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,\n 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf, 0x33, 0x93, 0x21, 0x3b,\n 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c, 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82,\n 0x83, 0x7e, 0x7f, 0x80, 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,\n 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88, 0xf9, 0xdc, 0x89, 0x9a,\n 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48, 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62,\n 0x0c, 0xe0, 0x1f, 0xef, 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,\n 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04, 0x1b, 0xfc, 0xac, 0xe6,\n 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea, 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b,\n 0xb1, 0x0d, 0xd6, 0xeb, 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,\n 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0, 0xcd, 0x1a, 0x41, 0x1c,\n ],\n} as const;\n","import type { FiniteFieldElement } from \"./finite-field-element\";\nimport { Polynomial } from \"./polynomial\";\n\n// File copied from <a href=\"https://gitlab.com/partisiablockchain/language/abi/zk-client\"> zk-client</a>.\n\n/**\n * Try to interpolate a polynomial that passes through the supplied points.\n *\n * @param xs x-coordinates in the points\n * @param ys y-coordinates in the points\n * @param zero 0 element in the Finite Field.\n * @param one 1 element in the Finite Field.\n *\n * @returns the interpolated polynomial or null if unable to interpolate\n */\nfunction interpolate<T extends FiniteFieldElement<T>>(\n xs: readonly T[],\n ys: T[],\n zero: T,\n one: T,\n): Polynomial<T> {\n if (xs.length !== ys.length) {\n throw new Error(\"xs and ys must be of same size\");\n }\n\n if (xs.length === 0) {\n throw new Error(\"xs and ys must have at least one element\");\n }\n\n const n = xs.length;\n const c: T[] = Array(n).fill(one);\n c[0] = one;\n\n for (let i = 0; i < n; i++) {\n for (let j = i; j > 0; j--) {\n c[j] = c[j - 1].subtract(c[j].multiply(xs[i]));\n }\n c[0] = c[0].multiply(xs[i].negate());\n }\n\n const coefficients: T[] = Array(n).fill(zero);\n // Stryker disable next-line ArrayDeclaration\n const tc: T[] = Array(n).fill(zero);\n tc[n - 1] = one;\n for (let i = 0; i < n; i++) {\n let denominator = one;\n for (let j = 0; j < n; j++) {\n if (i !== j) {\n denominator = denominator.multiply(xs[i].subtract(xs[j]));\n }\n }\n\n const t: T = ys[i].multiply(denominator.modInverse());\n coefficients[n - 1] = coefficients[n - 1].add(t.multiply(tc[n - 1]));\n\n for (let j = n - 2; j >= 0; j--) {\n tc[j] = c[j + 1].add(tc[j + 1].multiply(xs[i]));\n coefficients[j] = coefficients[j].add(t.multiply(tc[j]));\n }\n }\n\n return Polynomial.create(coefficients, zero);\n}\n\n/**\n * Interpolate the minimal polynomial that passes through all the supplied points. And verify that\n * the polynomial has a degree less that maximalDegree.\n *\n * @param xs x-coordinates in the points\n * @param ys y-coordinates in the points\n * @param zero 0 element in the Finite Field.\n * @param one 1 element in the Finite Field.\n * @param maximalDegree the expected maximal degree\n * @return the interpolated polynomial\n */\nfunction interpolateCheckDegree<T extends FiniteFieldElement<T>>(\n xs: readonly T[],\n ys: T[],\n maximalDegree: number,\n zero: T,\n one: T,\n): Polynomial<T> {\n const poly = interpolate(xs, ys, zero, one);\n if (poly.degree() > maximalDegree) {\n throw new Error(\n `Interpolated polynomial has too high degree. Expected maximal=${maximalDegree}, actual=${poly.degree()}`,\n );\n }\n return poly;\n}\n\n/**\n * Try to interpolate a polynomial that passes through at least <code>2 &sdot; maximalDegree + 1\n * </code> of the supplied points.\n *\n * <p>Element lists ({@code xs} and {@code ys}) must have same size.\n *\n * @param xs x-coordinates in the points\n * @param ys y-coordinates in the points\n * @param maximalDegree the expected maximal degree\n * @param zero 0 element in the Finite Field.\n * @param one 1 element in the Finite Field.\n *\n * @returns the interpolated polynomial or undefined if unable to interpolate\n */\nfunction interpolateIfPossible<T extends FiniteFieldElement<T>>(\n xs: readonly T[],\n ys: T[],\n maximalDegree: number,\n zero: T,\n one: T,\n): Polynomial<T> | undefined {\n if (xs.length !== ys.length) {\n throw new Error(\"xs and ys must be of same size\");\n }\n return interpolateIfPossibleInner(xs, ys, maximalDegree, zero, one);\n}\n\nfunction interpolateIfPossibleInner<T extends FiniteFieldElement<T>>(\n xs: readonly T[],\n ys: T[],\n maximalDegree: number,\n zero: T,\n one: T,\n): Polynomial<T> | undefined {\n if (xs.length <= 2 * maximalDegree + 1) {\n const interpolated = interpolate(xs, ys, zero, one);\n if (interpolated.degree() > maximalDegree) {\n return undefined;\n }\n return interpolated;\n }\n for (let removeIndex = 0; removeIndex < xs.length; removeIndex++) {\n const interpolated = interpolateIfPossibleInner(\n withoutIndex(xs, removeIndex),\n withoutIndex(ys, removeIndex),\n maximalDegree,\n zero,\n one,\n );\n if (interpolated !== undefined) {\n return interpolated;\n }\n }\n return undefined;\n}\n\nfunction withoutIndex<T>(values: readonly T[], removeIndex: number): T[] {\n return values.filter((_value, index, _array) => index != removeIndex);\n}\n\n/**\n * Utility for lagrange interpolation.\n */\nexport const Lagrange: {\n interpolate: typeof interpolate;\n interpolateCheckDegree: typeof interpolateCheckDegree;\n interpolateIfPossible: typeof interpolateIfPossible;\n} = {\n interpolate,\n interpolateCheckDegree,\n interpolateIfPossible,\n};\n","import { randomBytes } from \"crypto\";\nimport { F256 } from \"./f256\";\nimport { Lagrange } from \"./lagrange\";\nimport type { SecretShareFactory } from \"./secret-share-factory\";\nimport type { SecretShares } from \"./secret-shares\";\n\n/**\n * Configuration for creating and reconstructing shamir secret shares.\n *\n * <p>The <code>numToReconstruct</code> value must be at least <code>numMalicious + 1</code> to be able\n * to reconstruct.\n *\n * <p>If <code>numToReconstruct</code> is less than <code>2 * numMalicious + 1</code> then there must be\n * some other way to guarantee that the shares are correct, e.g. through commitments on-chain.\n */\nexport interface ShamirConfig {\n /** Maximum number of malicious nodes. Depends on the threat model. */\n numMalicious: number;\n /** Total number of nodes to receive a share. */\n numNodes: number;\n /** Minimum number of shares needed to reconstruct a secret. */\n numToReconstruct: number;\n}\n\n/** Factory for creating elements of {@link ShamirSecretShares}. */\nexport class ShamirFactory implements SecretShareFactory<ShamirSecretShares> {\n private readonly shamirConfig: ShamirConfig;\n\n /**\n * Create the {@link ShamirFactory}.\n *\n * @param shamirConfig configuration for creating and reconstructing shamir secret shares.\n */\n constructor(shamirConfig: ShamirConfig) {\n this.shamirConfig = shamirConfig;\n }\n\n fromPlainText(numNodes: number, plainText: Buffer): ShamirSecretShares {\n if (numNodes != this.shamirConfig.numNodes) {\n throw new Error(\n `This shamir factory expects there to be ${this.shamirConfig.numNodes} nodes, but there was ${numNodes}.`,\n );\n }\n const randomElements = randomBytes(plainText.length * this.shamirConfig.numMalicious);\n const alphas = F256.alphas(this.shamirConfig.numNodes);\n const shares: F256[][] = Array.from({ length: this.shamirConfig.numNodes }, () => []);\n for (let i = 0; i < plainText.length; i++) {\n const coefficients = [F256.createElement(plainText[i])];\n for (let j = 0; j < this.shamirConfig.numMalicious; j++) {\n coefficients.push(\n F256.createElement(randomElements[this.shamirConfig.numMalicious * i + j]),\n );\n }\n const poly = F256.createPoly(coefficients);\n for (let j = 0; j < this.shamirConfig.numNodes; j++) {\n shares[j].push(poly.evaluate(alphas[j]));\n }\n }\n\n return new ShamirSecretShares(this.shamirConfig, shares);\n }\n\n fromSharesBytes(shares: Array<Buffer | undefined>): ShamirSecretShares {\n const elementShares = shares.map((bytes) => {\n if (bytes == undefined) {\n return undefined;\n }\n const elements = [];\n for (let i = 0; i < bytes.length; i++) {\n elements.push(F256.createElement(bytes[i]));\n }\n return elements;\n });\n return new ShamirSecretShares(this.shamirConfig, elementShares);\n }\n}\n\n/**\n * Secure secret-sharing scheme based on shamir-secret sharing.\n *\n * <p>Supported number of shares ({@code N}): {@code 4}\n *\n * <p>Based on the java implementation of the secret-sharing client.\n *\n * @see <a href=\"https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing\">Shamir's secret sharing,\n * Wikipedia</a>\n */\nexport class ShamirSecretShares implements SecretShares {\n private readonly shares: Array<F256[] | undefined>;\n private readonly shamirConfig: ShamirConfig;\n\n constructor(shamirConfig: ShamirConfig, shares: Array<F256[] | undefined>) {\n if (shares.length != shamirConfig.numNodes) {\n throw new Error(`There must be ${shamirConfig.numNodes} nodes`);\n }\n const numReceivedShares = shares.filter((s) => s != undefined).length;\n if (numReceivedShares < shamirConfig.numToReconstruct) {\n throw new Error(\n `Must have received at least ${shamirConfig.numToReconstruct} shares to reconstruct. Received ${numReceivedShares}.`,\n );\n }\n this.shamirConfig = shamirConfig;\n this.shares = shares;\n }\n\n getShareBytes(nodeIndex: number): Buffer {\n const share = this.shares[nodeIndex];\n if (share == undefined) {\n throw new Error(\"Expected share to be defined\");\n }\n return Buffer.from(share.map((field) => field.value));\n }\n\n numShares(): number {\n return this.shamirConfig.numNodes;\n }\n\n reconstructPlainText(): Buffer {\n const alphas = F256.alphas(this.shamirConfig.numNodes);\n const definedAlphas: F256[] = [];\n const definedShares: F256[][] = [];\n for (let i = 0; i < this.shares.length; i++) {\n const share = this.shares[i];\n if (share != undefined) {\n definedAlphas.push(alphas[i]);\n definedShares.push(share);\n }\n }\n\n const reconstructedElements = [];\n const numElements = definedShares[0].length;\n for (let i = 0; i < numElements; i++) {\n const sharesOfIthElement = [];\n for (let j = 0; j < definedShares.length; j++) {\n sharesOfIthElement.push(definedShares[j][i]);\n }\n const interpolated = Lagrange.interpolateIfPossible(\n definedAlphas,\n sharesOfIthElement,\n this.shamirConfig.numMalicious,\n F256.ZERO,\n F256.ONE,\n );\n if (interpolated === undefined) {\n throw new Error(\"Unable to reconstruct secret\");\n }\n reconstructedElements.push(interpolated.getConstantTerm().value);\n }\n return Buffer.from(reconstructedElements);\n }\n\n public static readonly FACTORY: SecretShareFactory<ShamirSecretShares> = new ShamirFactory({\n numMalicious: 1,\n numNodes: 4,\n numToReconstruct: 2,\n });\n}\n\nexport function getRandomBytes(length: number): Buffer {\n const array = new Uint8Array(length);\n crypto.getRandomValues(array);\n\n return Buffer.from(array);\n}\n","import type { TypedDataDomain, TypedDataField } from \"ethers\";\n\nexport type PbcAddress = string;\nexport type Bytes32 = string;\nexport type Bytes24 = string;\nexport type Address = string;\nexport type Bytes = string;\n\nexport const UPLOAD_TYPES: Record<string, TypedDataField[]> = {\n UploadSignatureMessage: [\n { name: \"share_commitments\", type: \"bytes32[]\" },\n { name: \"recovering_addresses\", type: \"string[]\" },\n ],\n};\n\nexport const DOWNLOAD_TYPES: Record<string, TypedDataField[]> = {\n DownloadSignatureMessage: [\n { name: \"recovering_address\", type: \"string\" },\n { name: \"timestamp\", type: \"uint64\" },\n { name: \"public_key\", type: \"bytes32\" },\n ],\n};\n\nexport const UPDATE_TYPES: Record<string, TypedDataField[]> = {\n UpdateWalletsSignatureMessage: [\n { name: \"recovering_addresses\", type: \"string[]\" },\n { name: \"timestamp\", type: \"uint64\" },\n ],\n};\n\nexport const ADD_ADDRESS_TYPES: Record<string, TypedDataField[]> = {\n AddAddressSignatureMessage: [\n { name: \"recovering_address\", type: \"string\" },\n { name: \"address_to_add\", type: \"string\" },\n { name: \"timestamp\", type: \"uint64\" },\n ],\n};\n\nexport const REMOVE_ADDRESS_TYPES: Record<string, TypedDataField[]> = {\n RemoveAddressSignatureMessage: [\n { name: \"recovering_address\", type: \"string\" },\n { name: \"address_to_remove\", type: \"string\" },\n { name: \"timestamp\", type: \"uint64\" },\n ],\n};\n\nexport interface UploadSignatureMessage {\n share_commitments: Bytes32[];\n recovering_addresses: Address[];\n}\n\nexport interface Sharing {\n share_commitments: Bytes32[];\n recovering_addresses: Address[];\n share_data: Bytes;\n}\n\nexport interface DownloadSignatureMessage {\n recovering_address: Address;\n timestamp: number;\n public_key: Bytes32;\n}\n\nexport type DownloadRequest = DownloadSignatureMessage;\n\nexport interface AddAddressSignatureMessage {\n recovering_address: Address;\n address_to_add: Address;\n timestamp: number;\n}\n\nexport type AddAddressRequest = AddAddressSignatureMessage;\n\nexport interface RemoveAddressSignatureMessage {\n recovering_address: Address;\n address_to_remove: Address;\n timestamp: number;\n}\n\nexport type RemoveAddressRequest = RemoveAddressSignatureMessage;\n\nexport interface UpdateWalletsSignatureMessage {\n recovering_addresses: Address[];\n timestamp: number;\n}\n\nexport type UpdateWalletsRequest = UpdateWalletsSignatureMessage;\n\nexport interface EncryptedShare {\n encrypted_share: Bytes;\n public_key: Bytes32;\n nonce: Bytes24;\n}\n\nexport type DownloadMessageToSign = {\n domain: TypedDataDomain;\n types: Record<string, TypedDataField[]>;\n value: DownloadSignatureMessage;\n};\n\nexport type UploadMessageToSign = {\n domain: TypedDataDomain;\n types: Record<string, TypedDataField[]>;\n value: UploadSignatureMessage;\n};\n\nexport type AddAddressMessageToSign = {\n domain: TypedDataDomain;\n types: Record<string, TypedDataField[]>;\n value: AddAddressSignatureMessage;\n};\n\nexport type RemoveAddressMessageToSign = {\n domain: TypedDataDomain;\n types: Record<string, TypedDataField[]>;\n value: RemoveAddressSignatureMessage;\n};\n","import { WALLET_TYPES, type WalletType } from \"@idos-network/kwil-infra/actions\";\nimport {\n ChainControllerApi,\n Configuration,\n} from \"@partisiablockchain/blockchain-api-transaction-client\";\nimport { ethers, type TypedDataDomain } from \"ethers\";\nimport { EngineClient } from \"./engine-client\";\nimport { deserializeState } from \"./generated/IdosContract\";\nimport { getRandomBytes, ShamirFactory } from \"./secretsharing/shamir-secret-shares\";\nimport {\n ADD_ADDRESS_TYPES,\n type AddAddressMessageToSign,\n type AddAddressSignatureMessage,\n type Bytes,\n DOWNLOAD_TYPES,\n type DownloadMessageToSign,\n type DownloadSignatureMessage,\n type PbcAddress,\n REMOVE_ADDRESS_TYPES,\n type RemoveAddressMessageToSign,\n type RemoveAddressSignatureMessage,\n type Sharing,\n UPLOAD_TYPES,\n type UploadMessageToSign,\n type UploadSignatureMessage,\n} from \"./types\";\nimport invariant from \"tiny-invariant\";\n\nexport class Client {\n private readonly baseUrl: string;\n private readonly contractAddress: PbcAddress;\n private engines: EngineClient[] | undefined;\n private walletType!: WalletType;\n private signerAddress!: string;\n private signerPublicKey: string | undefined;\n private factory: ShamirFactory;\n private numNodes: number;\n\n constructor(\n baseUrl: string,\n contractAddress: PbcAddress,\n numMalicious: number,\n numNodes: number,\n numToReconstruct: number,\n walletType: WalletType,\n signerAddress: string,\n signerPublicKey?: string,\n ) {\n this.baseUrl = baseUrl;\n this.contractAddress = contractAddress;\n\n this.reconfigure(walletType, signerAddress, signerPublicKey);\n \n this.numNodes = numNodes;\n // TODO: Make these configurable from env variables\n this.factory = new ShamirFactory({ numMalicious, numNodes, numToReconstruct });\n }\n\n public reconfigure(\n walletType: WalletType,\n signerAddress: string,\n signerPublicKey?: string,\n ): void {\n // @deprecated\n // Remove this method after a while\n if ([\"evm\", \"xrpl\", \"near\", \"facesign\", \"stellar\"].includes(walletType as string)) {\n console.warn(\"Deprecated wallet type\", walletType, \", please upgrade to latest SDK version\");\n switch (walletType as string) {\n case \"evm\":\n walletType = \"EVM\";\n break;\n case \"xrpl\":\n walletType = \"XRPL\";\n break;\n case \"near\":\n walletType = \"NEAR\";\n break;\n case \"stellar\":\n walletType = \"Stellar\";\n break;\n case \"facesign\":\n walletType = \"FaceSign\";\n break;\n }\n }\n \n invariant(WALLET_TYPES.includes(walletType), `Invalid signer type: ${walletType}`);\n invariant(\n // XRPL, NEAR and FaceSign require a public key, EVM does not\n ([\"XRPL\", \"NEAR\", \"FaceSign\"].includes(walletType) && signerPublicKey) || walletType === \"EVM\",\n \"Signer public key is required for XRPL, NEAR and FaceSign\",\n );\n\n this.walletType = walletType;\n // Reset engines to force re-creation of them since they are using old signer information\n this.engines = undefined;\n this.signerAddress = signerAddress;\n if (signerPublicKey) this.signerPublicKey = signerPublicKey;\n }\n\n public async uploadSecret(\n id: string,\n uploadSignature: UploadSignatureMessage,\n signature: Bytes,\n blindedShares: Buffer[],\n ): Promise<{ status: string }> {\n const engineClients = await this.getEngines();\n const promises = [];\n for (let i = 0; i < engineClients.length; i++) {\n const engineClient = engineClients[i];\n const uploadRequest: Sharing = {\n ...uploadSignature,\n share_data: ethers.hexlify(blindedShares[i]),\n };\n promises.push(engineClient.sendUpload(id, uploadRequest, signature));\n }\n const statuses = await Promise.all(promises);\n\n if (statuses.every((item) => item === \"201\")) {\n return { status: \"success\" };\n }\n\n if (statuses.filter((item) => item === \"201\").length > 0) {\n return { status: \"partial-success\" };\n }\n\n return { status: \"failure\" };\n }\n\n public getBlindedShares(secret: Buffer): Buffer[] {\n // TODO: Make the number of nodes configurable from env variables\n const secretShares = this.factory.fromPlainText(this.numNodes, secret);\n var blindedShares: Buffer[] = [];\n for (let i = 0; i < secretShares.numShares(); i++) {\n blindedShares.push(Client.blindShare(secretShares.getShareBytes(i)));\n }\n return blindedShares;\n }\n\n public uploadMessageToSign(uploadRequest: UploadSignatureMessage): UploadMessageToSign {\n return {\n domain: this.getTypedDomain(),\n types: UPLOAD_TYPES,\n value: uploadRequest,\n };\n }\n\n public uploadRequest(blindedShares: Buffer[]): UploadSignatureMessage {\n console.log({ mpc: \"uploading to MPC\", walletType: this.walletType, address: this.signerAddress, publicKey: this.signerPublicKey });\n\n var address = \"\";\n switch (this.walletType) {\n case \"EVM\":\n address = `eip712:${this.signerAddress}`;\n break;\n case \"XRPL\":\n address = `XRPL:${this.signerPublicKey}`;\n break;\n case \"NEAR\":\n address = `NEAR:${this.signerPublicKey?.replace(\"ed25519:\", \"\")}`;\n break;\n case \"FaceSign\":\n address = `FACESIGN:${this.signerPublicKey}`;\n break;\n default:\n throw new Error(\"Invalid signer type\");\n }\n return {\n share_commitments: blindedShares.map((b) => ethers.keccak256(b)),\n recovering_addresses: [address],\n };\n }\n\n public downloadMessageToSign(downloadRequest: DownloadSignatureMessage): DownloadMessageToSign {\n return {\n domain: this.getTypedDomain(),\n types: DOWNLOAD_TYPES,\n value: downloadRequest,\n };\n }\n\n public downloadRequest(publicKey: Uint8Array): DownloadSignatureMessage {\n var address = \"\";\n switch (this.walletType) {\n case \"EVM\":\n address = `eip712:${this.signerAddress}`;\n break;\n case \"XRPL\":\n address = `XRPL:${this.signerPublicKey}`;\n break;\n case \"NEAR\":\n address = `NEAR:${this.signerPublicKey?.replace(\"ed25519:\", \"\")}`;\n break;\n case \"FaceSign\":\n address = `FACESIGN:${this.signerPublicKey}`;\n break;\n default:\n throw new Error(\"Invalid signer type\");\n }\n return {\n recovering_address: address,\n timestamp: Date.now(),\n public_key: ethers.hexlify(publicKey),\n };\n }\n\n public async downloadSecret(\n id: string,\n downloadRequest: DownloadSignatureMessage,\n signature: Bytes,\n secretKey: Uint8Array,\n ): Promise<{ status: string; secret: Buffer | undefined }> {\n const shares = [];\n const engineClients = await this.getEngines();\n for (let i = 0; i < engineClients.length; i++) {\n const engineClient = engineClients[i];\n shares.push(engineClient.downloadAndDecrypt(id, downloadRequest, signature, secretKey));\n }\n const secretShares = await Promise.all(shares);\n\n console.log({ secretSharesDownloadStatuses: secretShares.map((item) => item.status) });\n\n if (secretShares.every((item) => item.status === \"404\")) {\n return { status: \"not-stored\", secret: undefined };\n }\n\n var secret: Buffer;\n try {\n secret = this.factory\n .fromSharesBytes(secretShares.map((item) => item.share))\n .reconstructPlainText();\n return { status: \"ok\", secret };\n } catch (_e) {\n return { status: \"error\", secret: undefined };\n }\n }\n\n public addAddressMessageToSign(\n addressToAdd: string,\n publicKey: string | undefined,\n addressToAddType: string,\n ): AddAddressMessageToSign {\n var address = \"\";\n switch (this.walletType) {\n case \"EVM\":\n address = `eip712:${this.signerAddress}`;\n break;\n case \"XRPL\":\n address = `XRPL:${this.signerPublicKey}`;\n break;\n case \"NEAR\":\n address = `NEAR:${this.signerPublicKey?.replace(\"ed25519:\", \"\")}`;\n break;\n case \"FaceSign\":\n address = `FACESIGN:${this.signerPublicKey}`;\n break;\n default:\n throw new Error(\"Invalid signer type\");\n }\n\n var addressToAddFormatted = \"\";\n // @deprecated toLowerCase remove when we have updated the SDK\n switch (addressToAddType.toLowerCase()) {\n case \"evm\":\n addressToAddFormatted = `eip712:${addressToAdd}`;\n break;\n case \"xrpl\":\n addressToAddFormatted = `XRPL:${publicKey}`;\n break;\n case \"near\":\n addressToAddFormatted = `NEAR:${publicKey?.replace(\"ed25519:\", \"\")}`;\n break;\n case \"facesign\":\n addressToAddFormatted = `FACESIGN:${publicKey}`;\n break;\n default:\n throw new Error(\"Invalid address to add type\");\n }\n\n const value = {\n recovering_address: address,\n address_to_add: addressToAddFormatted,\n timestamp: Date.now(),\n };\n\n return {\n domain: this.getTypedDomain(),\n types: ADD_ADDRESS_TYPES,\n value,\n };\n }\n\n public removeAddressMessageToSign(\n addressToRemove: string,\n publicKey: string | undefined,\n addressToRemoveType: string,\n ): RemoveAddressMessageToSign {\n var address = \"\";\n switch (this.walletType) {\n case \"EVM\":\n address = `eip712:${this.signerAddress}`;\n break;\n case \"XRPL\":\n address = `XRPL:${this.signerPublicKey}`;\n break;\n case \"NEAR\":\n address = `NEAR:${this.signerPublicKey?.replace(\"ed25519:\", \"\")}`;\n break;\n case \"FaceSign\":\n address = `FACESIGN:${this.signerPublicKey}`;\n break;\n default:\n throw new Error(\"Invalid signer type\");\n }\n\n var addressToRemoveFormatted = \"\";\n // @deprecated toLowerCase remove when we have updated the SDK\n switch (addressToRemoveType.toLowerCase()) {\n case \"evm\":\n addressToRemoveFormatted = `eip712:${addressToRemove}`;\n break;\n case \"xrpl\":\n addressToRemoveFormatted = `XRPL:${publicKey}`;\n break;\n case \"near\":\n addressToRemoveFormatted = `NEAR:${publicKey?.replace(\"ed25519:\", \"\")}`;\n break;\n case \"facesign\":\n addressToRemoveFormatted = `FACESIGN:${publicKey}`;\n break;\n default:\n throw new Error(\"Invalid address to remove type\");\n }\n\n const value = {\n recovering_address: address,\n address_to_remove: addressToRemoveFormatted,\n timestamp: Date.now(),\n };\n return {\n domain: this.getTypedDomain(),\n types: REMOVE_ADDRESS_TYPES,\n value,\n };\n }\n\n public async addAddress(\n userId: string,\n message: AddAddressSignatureMessage,\n signature: string,\n ): Promise<string> {\n const engineClients = await this.getEngines();\n const promises = [];\n for (let i = 0; i < engineClients.length; i++) {\n const engineClient = engineClients[i];\n promises.push(engineClient.sendAddAddress(userId, message, signature));\n }\n const statuses = await Promise.all(promises);\n\n if (statuses.every((item) => item === \"200\")) {\n return \"success\";\n }\n\n return \"failure\";\n }\n\n public async removeAddress(\n userId: string,\n message: RemoveAddressSignatureMessage,\n signature: string,\n ): Promise<string> {\n const engineClients = await this.getEngines();\n const promises = [];\n for (let i = 0; i < engineClients.length; i++) {\n const engineClient = engineClients[i];\n promises.push(engineClient.sendRemoveAddress(userId, message, signature));\n }\n const statuses = await Promise.all(promises);\n\n if (statuses.every((item) => item === \"200\")) {\n return \"success\";\n }\n\n return \"failure\";\n }\n\n private getTypedDomain(): TypedDataDomain {\n return {\n name: \"idOS secret store contract\",\n version: \"1\",\n verifyingContract: `0x${this.contractAddress.substring(2)}`,\n };\n }\n\n private async getEngines(): Promise<EngineClient[]> {\n if (this.engines === undefined) {\n const chainController = new ChainControllerApi(new Configuration({ basePath: this.baseUrl }));\n const rawState = await chainController.getContract({ address: this.contractAddress });\n // oxlint-disable-next-line typescript/no-non-null-assertion -- we know serializedContract is present here\n const state = deserializeState(Buffer.from(rawState.serializedContract!, \"base64\"));\n this.engines = state.nodes.map(\n (value) => new EngineClient(value.endpoint, this.contractAddress, this.walletType),\n );\n }\n return this.engines;\n }\n\n private static blindShare(share: Buffer): Buffer {\n return Buffer.concat([getRandomBytes(32), share]);\n }\n}\n"],"mappings":";;;;;;;;AAAA,MAAM,cAAc;CAClB,QAAQ;CACR,gBAAgB;CACjB;AAQD,SAAS,aAAgB,QAAqB,SAAiC,aAAgB;CAC7F,MAAM,SAAsB;EAAE;EAAQ;EAAS,MAAM;EAAM;CAE3D,IAAI,eAAe,MACjB,OAAO,OAAO,KAAK,UAAU,YAAY;CAE3C,OAAO;;;;;;;;;;AAsBT,SAAgB,WACd,KACA,QACA,SACiB;CACjB,MAAM,UAAU,aAAa,OAAO;EAAE,GAAG;EAAa,GAAG;EAAS,EAAE,OAAO;CAC3E,OAAO,MAAM,KAAK,QAAQ,CACvB,KAAK,OAAO,aAAa;EAExB,MAAM,eAAe,MADC,SAAS,OACS,CAAC,MAAM;EAC/C,QAAQ,IAAI;GAAE,cAAc,SAAS;GAAQ;GAAc,CAAC;EAC5D,OAAO,SAAS,OAAO,UAAU;GACjC,CACD,OAAO,UAAU;EAChB,QAAQ,MAAM,MAAM;EACpB,OAAO;GACP;;;;;;;;;;AAWN,SAAgB,aACd,KACA,QACA,SACiB;CACjB,MAAM,UAAU,aAAa,SAAS;EAAE,GAAG;EAAa,GAAG;EAAS,EAAE,OAAO;CAC7E,OAAO,MAAM,KAAK,QAAQ,CACvB,KAAK,OAAO,aAAa;EAExB,MAAM,eAAe,MADC,SAAS,OACS,CAAC,MAAM;EAC/C,QAAQ,IAAI;GAAE,cAAc,SAAS;GAAQ;GAAc,CAAC;EAC5D,OAAO,SAAS,OAAO,UAAU;GACjC,CACD,OAAO,UAAU;EAChB,QAAQ,MAAM,MAAM;EACpB,OAAO;GACP;;;;;;;;;;AAWN,SAAgB,YACd,KACA,QACA,SACkD;CAClD,MAAM,UAAU,aAAa,QAAQ;EAAE,GAAG;EAAa,GAAG;EAAS,EAAE,OAAO;CAC5E,OAAO,YAAe,MAAM,KAAK,QAAQ,CAAC;;AAG5C,SAAS,YACP,SACkD;CAClD,OAAO,QACJ,KAAK,OAAO,aAAa;EAExB,MAAM,eAAe,MADC,SAAS,OACS,CAAC,MAAM;EAC/C,QAAQ,IAAI;GAAE,cAAc,SAAS;GAAQ;GAAc,CAAC;EAE5D,IAAI,SAAS,WAAW,KAAK;GAC3B,MAAM,OAAQ,MAAM,SAAS,MAAM;GACnC,OAAO;IAAE,QAAQ,SAAS,OAAO,UAAU;IAAE,MAAM;IAAM;;EAE3D,OAAO;GAAE,QAAQ,SAAS,OAAO,UAAU;GAAE,MAAM,KAAA;GAAW;GAC9D,CACD,OAAO,UAAU;EAChB,QAAQ,MAAM,MAAM;EACpB,OAAO;GAAE,QAAQ;GAAe,MAAM,KAAA;GAAW;GACjD;;;;ACzGN,IAAa,eAAb,MAA0B;CACxB;CACA;CACA;CAEA,YAAY,SAAiB,iBAA6B,YAAwB;EAChF,KAAK,kBAAkB;EACvB,KAAK,UAAU;EACf,KAAK,aAAa;;CAGpB,cAAsB,WAA2C;EAC/D,IAAI;EACJ,QAAQ,KAAK,YAAb;GACE,KAAK;IACH,SAAS;IACT;GACF,KAAK;IACH,SAAS;IACT;GACF,KAAK;IACH,SAAS;IACT;GACF,KAAK;IACH,SAAS;IACT;GACF,SACE,SAAS;;EAGb,OAAO,EACL,eAAe,GAAG,OAAO,GAAG,aAC7B;;CAGH,MAAa,WAAW,IAAY,eAAwB,WAAmC;EAC7F,MAAM,aAAa,KAAK,cAAc,UAAU;EAChD,MAAM,MAAM,GAAG,KAAK,QAAQ,YAAY,KAAK,gBAAgB,UAAU;EACvE,MAAM,SAAS,MAAM,WAAW,KAAK,eAAe,WAAW;EAC/D,IAAI,WAAW,OACb,MAAM,IAAI,MAAM,4BAA4B,KAAK,gBAAgB,MAAM,MAAM;EAE/E,OAAO;;CAGT,MAAa,aACX,IACA,iBACA,WAC+D;EAC/D,MAAM,aAAa,KAAK,cAAc,UAAU;EAEhD,OAAO,MAAM,YAAY,GADV,KAAK,QAAQ,YAAY,KAAK,gBAAgB,UAAU,MACzC,iBAAiB,WAAW;;CAG5D,MAAa,mBACX,IACA,iBACA,WACA,WACwD;EACxD,MAAM,EAAE,QAAQ,MAAM,mBAAmB,MAAM,KAAK,aAClD,IACA,iBACA,UACD;EACD,IAAI,mBAAmB,KAAA,GACrB,OAAO;GAAE,OAAO,KAAA;GAAW;GAAQ;EAErC,MAAM,kBAAkB,OAAO,SAAS,eAAe,gBAAgB;EACvE,MAAM,kBAAkB,OAAO,SAAS,eAAe,WAAW;EAClE,MAAM,cAAc,OAAO,SAAS,eAAe,MAAM;EACzD,MAAM,OAAO,KAAK,IAAI,KAAK,iBAAiB,aAAa,iBAAiB,UAAU;EACpF,IAAI,QAAQ,MACV,OAAO;GAAE,OAAO,KAAA;GAAW,QAAQ;GAAkB;EAGvD,OAAO;GAAE,OAAO,OAAO,KAAK,KAAK,SAAS,GAAG,CAAC;GAAE;GAAQ;;CAG1D,MAAa,WACX,IACA,eACA,WACiB;EACjB,MAAM,aAAqC,EACzC,eAAe,UAAU,aAC1B;EAED,MAAM,MAAM,GAAG,KAAK,QAAQ,YAAY,KAAK,gBAAgB,UAAU;EACvE,MAAM,KAAK,MAAM,aAAa,KAAK,eAAe,WAAW;EAE7D,IAAI,CAAC,IACH,MAAM,IAAI,MAAM,6BAA6B,KAAK,gBAAgB,MAAM,MAAM;EAGhF,OAAO;;CAGT,MAAa,eACX,IACA,YACA,WACiB;EACjB,MAAM,aAAa,KAAK,cAAc,UAAU;EAChD,MAAM,MAAM,GAAG,KAAK,QAAQ,YAAY,KAAK,gBAAgB,UAAU,GAAG;EAC1E,MAAM,SAAS,MAAM,aAAa,KAAK,YAAY,WAAW;EAC9D,IAAI,WAAW,OACb,MAAM,IAAI,MAAM,4BAA4B,GAAG,MAAM,MAAM;EAG7D,OAAO;;CAGT,MAAa,kBACX,IACA,eACA,WACiB;EACjB,MAAM,aAAa,KAAK,cAAc,UAAU;EAChD,MAAM,MAAM,GAAG,KAAK,QAAQ,YAAY,KAAK,gBAAgB,UAAU,GAAG;EAC1E,MAAM,SAAS,MAAM,aAAa,KAAK,eAAe,WAAW;EACjE,IAAI,WAAW,OACb,MAAM,IAAI,MAAM,+BAA+B,GAAG,MAAM,MAAM;EAGhE,OAAO;;;;;AC9HX,IAAa,eAAb,MAA0B;CACxB;CACA;CAEA,YACE,QACA,SACA;EACA,KAAK,WAAW;EAChB,KAAK,UAAU;;CAEjB,yBAAgC,QAAiC;EAC/D,MAAM,kBAAkB,OAAO,SAAS;EACxC,MAAM,QAAsB,EAAE;EAC9B,KAAK,IAAI,UAAU,GAAG,UAAU,iBAAiB,WAAW;GAC1D,MAAM,aAAyB,KAAK,sBAAsB,OAAO;GACjE,MAAM,KAAK,WAAW;;EAExB,OAAO,EAAE,OAAO;;CAElB,sBAA6B,QAA8B;EAGzD,OAAO;GAAE,SAF0B,OAAO,aAE1B;GAAE,UADO,OAAO,YACN;GAAE;;CAE9B,MAAa,WAAmC;EAC9C,MAAM,QAAQ,MAAM,KAAK,SAAS,uBAAuB,KAAK,SAAU;EACxE,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,MAAM,4BAA4B;EAE9C,MAAM,QAAQ,aAAa,mBAAmB,MAAM;EACpD,OAAO,KAAK,yBAAyB,MAAM;;;AAkC/C,SAAgB,iBACd,OACA,QACA,SACe;CACf,IAAI,OAAO,SAAS,MAAM,EAAE;EAC1B,MAAM,QAAQ,aAAa,mBAAmB,MAAM;EACpD,OAAO,IAAI,aAAa,QAAQ,QAAQ,CAAC,yBAAyB,MAAM;;CAE1E,MAAM,QAAQ,aAAa,mBAAmB,MAAM,MAAM;CAC1D,OAAO,IAAI,aAAa,MAAM,QAAQ,MAAM,QAAQ,CAAC,yBAAyB,MAAM;;;;;;;;;ACnFtF,IAAa,aAAb,MAAa,WAA4C;CACvD;CAEA,YAAoB,cAAmB;EACrC,KAAK,eAAe;;;;;;;;;;;CAYtB,OAAO,OAAwC,cAAmB,MAAwB;EACxF,OAAO,IAAI,WAAc,WAAW,iBAAiB,cAAc,KAAK,CAAC;;CAG3E,OAAe,iBACb,cACA,MACK;EACL,KAAK,IAAI,IAAI,aAAa,SAAS,GAAG,KAAK,GAAG,KAC5C,IAAI,CAAC,aAAa,GAAG,QAAQ,EAC3B,OAAO,aAAa,MAAM,GAAG,IAAI,EAAE;EAGvC,OAAO,CAAC,KAAK;;;;;;;CAQf,kBAAuB;EACrB,OAAO,KAAK,aAAa,OAAO;;;;;;;CAQlC,SAAiB;EACf,OAAO,KAAK,aAAa,SAAS;;;;;;;CAQpC,kBAAqB;EACnB,OAAO,KAAK,aAAa;;;;;;;;;CAU3B,SAAS,OAAa;EACpB,MAAM,SAAS,KAAK,QAAQ;EAE5B,IAAI,SAAS,KAAK,aAAa;EAC/B,KAAK,IAAI,IAAI,SAAS,GAAG,KAAK,GAAG,EAAE,GAEjC,SADgB,KAAK,aAAa,GACjB,IAAI,MAAM,SAAS,OAAO,CAAC;EAE9C,OAAO;;;;;;AC7EX,IAAa,OAAb,MAAa,KAAyC;CACpD;CAEA,YAAoB,OAAe;EACjC,KAAK,QAAQ;;;;;CAMf,OAAgB,OAAa,KAAK,cAAc,EAAE;;;;CAKlD,OAAgB,MAAY,KAAK,cAAc,EAAE;;;;;CAMjD,OAAO,cAAc,OAAqB;EACxC,OAAO,IAAI,KAAK,QAAQ,IAAK;;;;;;CAO/B,OAAO,OAAO,UAAmC;EAC/C,OAAO,MAAM,KAAK,EAAE,QAAQ,UAAU,GAAG,QAAQ,QAAQ,KAAK,cAAc,MAAM,EAAE,CAAC;;;;;;CAOvF,OAAO,WAAW,cAAwC;EACxD,OAAO,WAAW,OAAO,cAAc,KAAK,KAAK;;;CAInD,IAAI,OAAmB;EACrB,OAAO,UAAU,SAAS,KAAK,QAAQ,MAAM;;;CAI/C,UAAU,OAAsB;EAC9B,OAAO,KAAK,UAAU,MAAM;;;CAI9B,QAAiB;EACf,OAAO,KAAK,UAAU;;;CAIxB,SAAkB;EAChB,OAAO,KAAK,UAAU;;;CAIxB,aAAmB;EACjB,OAAO,UAAU,SAAS,UAAU,sBAAsB,KAAK;;;CAIjE,SAAS,OAAmB;EAC1B,IAAI,IAAI,KAAK;EACb,IAAI,IAAI,MAAM;EACd,IAAI;EACJ,IAAI,IAAI;EACR,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC1B,KAAK,IAAK,EAAE,IAAI,KAAK,KAAM;GAC3B,IAAI,EAAG,KAAK,IAAK,KAAK;GACtB,KAAM,KAAK,IAAM,MAAc,KAAM;GACrC,IAAI,KAAK;;EAEX,OAAO,UAAU,SAAS;;;CAI5B,SAAe;EACb,OAAO;;;CAIT,aAAmB;EACjB,MAAM,IAAI,MAAM,kBAAkB;;;CAIpC,SAAS,OAAmB;EAC1B,OAAO,KAAK,IAAI,MAAM;;;AAI1B,MAAM,YAAY;CAChB,UAAU,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,QAAQ,QAAQ,KAAK,cAAc,IAAI,CAAC;CAC/E,uBAAuB;EACrB;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC1F;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAC3F;CACF;;;;;;;;;;;;;AC1GD,SAAS,YACP,IACA,IACA,MACA,KACe;CACf,IAAI,GAAG,WAAW,GAAG,QACnB,MAAM,IAAI,MAAM,iCAAiC;CAGnD,IAAI,GAAG,WAAW,GAChB,MAAM,IAAI,MAAM,2CAA2C;CAG7D,MAAM,IAAI,GAAG;CACb,MAAM,IAAS,MAAM,EAAE,CAAC,KAAK,IAAI;CACjC,EAAE,KAAK;CAEP,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,EAAE,KAAK,EAAE,IAAI,GAAG,SAAS,EAAE,GAAG,SAAS,GAAG,GAAG,CAAC;EAEhD,EAAE,KAAK,EAAE,GAAG,SAAS,GAAG,GAAG,QAAQ,CAAC;;CAGtC,MAAM,eAAoB,MAAM,EAAE,CAAC,KAAK,KAAK;CAE7C,MAAM,KAAU,MAAM,EAAE,CAAC,KAAK,KAAK;CACnC,GAAG,IAAI,KAAK;CACZ,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,IAAI,cAAc;EAClB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,IAAI,MAAM,GACR,cAAc,YAAY,SAAS,GAAG,GAAG,SAAS,GAAG,GAAG,CAAC;EAI7D,MAAM,IAAO,GAAG,GAAG,SAAS,YAAY,YAAY,CAAC;EACrD,aAAa,IAAI,KAAK,aAAa,IAAI,GAAG,IAAI,EAAE,SAAS,GAAG,IAAI,GAAG,CAAC;EAEpE,KAAK,IAAI,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;GAC/B,GAAG,KAAK,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,GAAG,CAAC;GAC/C,aAAa,KAAK,aAAa,GAAG,IAAI,EAAE,SAAS,GAAG,GAAG,CAAC;;;CAI5D,OAAO,WAAW,OAAO,cAAc,KAAK;;;;;;;;;;;;;AAc9C,SAAS,uBACP,IACA,IACA,eACA,MACA,KACe;CACf,MAAM,OAAO,YAAY,IAAI,IAAI,MAAM,IAAI;CAC3C,IAAI,KAAK,QAAQ,GAAG,eAClB,MAAM,IAAI,MACR,iEAAiE,cAAc,WAAW,KAAK,QAAQ,GACxG;CAEH,OAAO;;;;;;;;;;;;;;;;AAiBT,SAAS,sBACP,IACA,IACA,eACA,MACA,KAC2B;CAC3B,IAAI,GAAG,WAAW,GAAG,QACnB,MAAM,IAAI,MAAM,iCAAiC;CAEnD,OAAO,2BAA2B,IAAI,IAAI,eAAe,MAAM,IAAI;;AAGrE,SAAS,2BACP,IACA,IACA,eACA,MACA,KAC2B;CAC3B,IAAI,GAAG,UAAU,IAAI,gBAAgB,GAAG;EACtC,MAAM,eAAe,YAAY,IAAI,IAAI,MAAM,IAAI;EACnD,IAAI,aAAa,QAAQ,GAAG,eAC1B;EAEF,OAAO;;CAET,KAAK,IAAI,cAAc,GAAG,cAAc,GAAG,QAAQ,eAAe;EAChE,MAAM,eAAe,2BACnB,aAAa,IAAI,YAAY,EAC7B,aAAa,IAAI,YAAY,EAC7B,eACA,MACA,IACD;EACD,IAAI,iBAAiB,KAAA,GACnB,OAAO;;;AAMb,SAAS,aAAgB,QAAsB,aAA0B;CACvE,OAAO,OAAO,QAAQ,QAAQ,OAAO,WAAW,SAAS,YAAY;;;;;AAMvE,MAAa,WAIT;CACF;CACA;CACA;CACD;;;;ACzID,IAAa,gBAAb,MAA6E;CAC3E;;;;;;CAOA,YAAY,cAA4B;EACtC,KAAK,eAAe;;CAGtB,cAAc,UAAkB,WAAuC;EACrE,IAAI,YAAY,KAAK,aAAa,UAChC,MAAM,IAAI,MACR,2CAA2C,KAAK,aAAa,SAAS,wBAAwB,SAAS,GACxG;EAEH,MAAM,iBAAiB,YAAY,UAAU,SAAS,KAAK,aAAa,aAAa;EACrF,MAAM,SAAS,KAAK,OAAO,KAAK,aAAa,SAAS;EACtD,MAAM,SAAmB,MAAM,KAAK,EAAE,QAAQ,KAAK,aAAa,UAAU,QAAQ,EAAE,CAAC;EACrF,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;GACzC,MAAM,eAAe,CAAC,KAAK,cAAc,UAAU,GAAG,CAAC;GACvD,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,aAAa,cAAc,KAClD,aAAa,KACX,KAAK,cAAc,eAAe,KAAK,aAAa,eAAe,IAAI,GAAG,CAC3E;GAEH,MAAM,OAAO,KAAK,WAAW,aAAa;GAC1C,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,aAAa,UAAU,KAC9C,OAAO,GAAG,KAAK,KAAK,SAAS,OAAO,GAAG,CAAC;;EAI5C,OAAO,IAAI,mBAAmB,KAAK,cAAc,OAAO;;CAG1D,gBAAgB,QAAuD;EACrE,MAAM,gBAAgB,OAAO,KAAK,UAAU;GAC1C,IAAI,SAAS,KAAA,GACX;GAEF,MAAM,WAAW,EAAE;GACnB,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAChC,SAAS,KAAK,KAAK,cAAc,MAAM,GAAG,CAAC;GAE7C,OAAO;IACP;EACF,OAAO,IAAI,mBAAmB,KAAK,cAAc,cAAc;;;;;;;;;;;;;AAcnE,IAAa,qBAAb,MAAwD;CACtD;CACA;CAEA,YAAY,cAA4B,QAAmC;EACzE,IAAI,OAAO,UAAU,aAAa,UAChC,MAAM,IAAI,MAAM,iBAAiB,aAAa,SAAS,QAAQ;EAEjE,MAAM,oBAAoB,OAAO,QAAQ,MAAM,KAAK,KAAA,EAAU,CAAC;EAC/D,IAAI,oBAAoB,aAAa,kBACnC,MAAM,IAAI,MACR,+BAA+B,aAAa,iBAAiB,mCAAmC,kBAAkB,GACnH;EAEH,KAAK,eAAe;EACpB,KAAK,SAAS;;CAGhB,cAAc,WAA2B;EACvC,MAAM,QAAQ,KAAK,OAAO;EAC1B,IAAI,SAAS,KAAA,GACX,MAAM,IAAI,MAAM,+BAA+B;EAEjD,OAAO,OAAO,KAAK,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC;;CAGvD,YAAoB;EAClB,OAAO,KAAK,aAAa;;CAG3B,uBAA+B;EAC7B,MAAM,SAAS,KAAK,OAAO,KAAK,aAAa,SAAS;EACtD,MAAM,gBAAwB,EAAE;EAChC,MAAM,gBAA0B,EAAE;EAClC,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;GAC3C,MAAM,QAAQ,KAAK,OAAO;GAC1B,IAAI,SAAS,KAAA,GAAW;IACtB,cAAc,KAAK,OAAO,GAAG;IAC7B,cAAc,KAAK,MAAM;;;EAI7B,MAAM,wBAAwB,EAAE;EAChC,MAAM,cAAc,cAAc,GAAG;EACrC,KAAK,IAAI,IAAI,GAAG,IAAI,aAAa,KAAK;GACpC,MAAM,qBAAqB,EAAE;GAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KACxC,mBAAmB,KAAK,cAAc,GAAG,GAAG;GAE9C,MAAM,eAAe,SAAS,sBAC5B,eACA,oBACA,KAAK,aAAa,cAClB,KAAK,MACL,KAAK,IACN;GACD,IAAI,iBAAiB,KAAA,GACnB,MAAM,IAAI,MAAM,+BAA+B;GAEjD,sBAAsB,KAAK,aAAa,iBAAiB,CAAC,MAAM;;EAElE,OAAO,OAAO,KAAK,sBAAsB;;CAG3C,OAAuB,UAAkD,IAAI,cAAc;EACzF,cAAc;EACd,UAAU;EACV,kBAAkB;EACnB,CAAC;;AAGJ,SAAgB,eAAe,QAAwB;CACrD,MAAM,QAAQ,IAAI,WAAW,OAAO;CACpC,OAAO,gBAAgB,MAAM;CAE7B,OAAO,OAAO,KAAK,MAAM;;;;AC1J3B,MAAa,eAAiD,EAC5D,wBAAwB,CACtB;CAAE,MAAM;CAAqB,MAAM;CAAa,EAChD;CAAE,MAAM;CAAwB,MAAM;CAAY,CACnD,EACF;AAED,MAAa,iBAAmD,EAC9D,0BAA0B;CACxB;EAAE,MAAM;EAAsB,MAAM;EAAU;CAC9C;EAAE,MAAM;EAAa,MAAM;EAAU;CACrC;EAAE,MAAM;EAAc,MAAM;EAAW;CACxC,EACF;AAED,MAAa,eAAiD,EAC5D,+BAA+B,CAC7B;CAAE,MAAM;CAAwB,MAAM;CAAY,EAClD;CAAE,MAAM;CAAa,MAAM;CAAU,CACtC,EACF;AAED,MAAa,oBAAsD,EACjE,4BAA4B;CAC1B;EAAE,MAAM;EAAsB,MAAM;EAAU;CAC9C;EAAE,MAAM;EAAkB,MAAM;EAAU;CAC1C;EAAE,MAAM;EAAa,MAAM;EAAU;CACtC,EACF;AAED,MAAa,uBAAyD,EACpE,+BAA+B;CAC7B;EAAE,MAAM;EAAsB,MAAM;EAAU;CAC9C;EAAE,MAAM;EAAqB,MAAM;EAAU;CAC7C;EAAE,MAAM;EAAa,MAAM;EAAU;CACtC,EACF;;;AChBD,IAAa,SAAb,MAAa,OAAO;CAClB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YACE,SACA,iBACA,cACA,UACA,kBACA,YACA,eACA,iBACA;EACA,KAAK,UAAU;EACf,KAAK,kBAAkB;EAEvB,KAAK,YAAY,YAAY,eAAe,gBAAgB;EAE5D,KAAK,WAAW;EAEhB,KAAK,UAAU,IAAI,cAAc;GAAE;GAAc;GAAU;GAAkB,CAAC;;CAGhF,YACE,YACA,eACA,iBACM;EAGN,IAAI;GAAC;GAAO;GAAQ;GAAQ;GAAY;GAAU,CAAC,SAAS,WAAqB,EAAE;GACjF,QAAQ,KAAK,0BAA0B,YAAY,yCAAyC;GAC5F,QAAQ,YAAR;IACE,KAAK;KACH,aAAa;KACb;IACF,KAAK;KACH,aAAa;KACb;IACF,KAAK;KACH,aAAa;KACb;IACF,KAAK;KACH,aAAa;KACb;IACF,KAAK;KACH,aAAa;KACb;;;EAIN,UAAU,aAAa,SAAS,WAAW,EAAE,wBAAwB,aAAa;EAClF,UAEG;GAAC;GAAQ;GAAQ;GAAW,CAAC,SAAS,WAAW,IAAI,mBAAoB,eAAe,OACzF,4DACD;EAED,KAAK,aAAa;EAElB,KAAK,UAAU,KAAA;EACf,KAAK,gBAAgB;EACrB,IAAI,iBAAiB,KAAK,kBAAkB;;CAG9C,MAAa,aACX,IACA,iBACA,WACA,eAC6B;EAC7B,MAAM,gBAAgB,MAAM,KAAK,YAAY;EAC7C,MAAM,WAAW,EAAE;EACnB,KAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;GAC7C,MAAM,eAAe,cAAc;GACnC,MAAM,gBAAyB;IAC7B,GAAG;IACH,YAAY,OAAO,QAAQ,cAAc,GAAG;IAC7C;GACD,SAAS,KAAK,aAAa,WAAW,IAAI,eAAe,UAAU,CAAC;;EAEtE,MAAM,WAAW,MAAM,QAAQ,IAAI,SAAS;EAE5C,IAAI,SAAS,OAAO,SAAS,SAAS,MAAM,EAC1C,OAAO,EAAE,QAAQ,WAAW;EAG9B,IAAI,SAAS,QAAQ,SAAS,SAAS,MAAM,CAAC,SAAS,GACrD,OAAO,EAAE,QAAQ,mBAAmB;EAGtC,OAAO,EAAE,QAAQ,WAAW;;CAG9B,iBAAwB,QAA0B;EAEhD,MAAM,eAAe,KAAK,QAAQ,cAAc,KAAK,UAAU,OAAO;EACtE,IAAI,gBAA0B,EAAE;EAChC,KAAK,IAAI,IAAI,GAAG,IAAI,aAAa,WAAW,EAAE,KAC5C,cAAc,KAAK,OAAO,WAAW,aAAa,cAAc,EAAE,CAAC,CAAC;EAEtE,OAAO;;CAGT,oBAA2B,eAA4D;EACrF,OAAO;GACL,QAAQ,KAAK,gBAAgB;GAC7B,OAAO;GACP,OAAO;GACR;;CAGH,cAAqB,eAAiD;EACpE,QAAQ,IAAI;GAAE,KAAK;GAAoB,YAAY,KAAK;GAAY,SAAS,KAAK;GAAe,WAAW,KAAK;GAAiB,CAAC;EAEnI,IAAI,UAAU;EACd,QAAQ,KAAK,YAAb;GACE,KAAK;IACH,UAAU,UAAU,KAAK;IACzB;GACF,KAAK;IACH,UAAU,QAAQ,KAAK;IACvB;GACF,KAAK;IACH,UAAU,QAAQ,KAAK,iBAAiB,QAAQ,YAAY,GAAG;IAC/D;GACF,KAAK;IACH,UAAU,YAAY,KAAK;IAC3B;GACF,SACE,MAAM,IAAI,MAAM,sBAAsB;;EAE1C,OAAO;GACL,mBAAmB,cAAc,KAAK,MAAM,OAAO,UAAU,EAAE,CAAC;GAChE,sBAAsB,CAAC,QAAQ;GAChC;;CAGH,sBAA6B,iBAAkE;EAC7F,OAAO;GACL,QAAQ,KAAK,gBAAgB;GAC7B,OAAO;GACP,OAAO;GACR;;CAGH,gBAAuB,WAAiD;EACtE,IAAI,UAAU;EACd,QAAQ,KAAK,YAAb;GACE,KAAK;IACH,UAAU,UAAU,KAAK;IACzB;GACF,KAAK;IACH,UAAU,QAAQ,KAAK;IACvB;GACF,KAAK;IACH,UAAU,QAAQ,KAAK,iBAAiB,QAAQ,YAAY,GAAG;IAC/D;GACF,KAAK;IACH,UAAU,YAAY,KAAK;IAC3B;GACF,SACE,MAAM,IAAI,MAAM,sBAAsB;;EAE1C,OAAO;GACL,oBAAoB;GACpB,WAAW,KAAK,KAAK;GACrB,YAAY,OAAO,QAAQ,UAAU;GACtC;;CAGH,MAAa,eACX,IACA,iBACA,WACA,WACyD;EACzD,MAAM,SAAS,EAAE;EACjB,MAAM,gBAAgB,MAAM,KAAK,YAAY;EAC7C,KAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;GAC7C,MAAM,eAAe,cAAc;GACnC,OAAO,KAAK,aAAa,mBAAmB,IAAI,iBAAiB,WAAW,UAAU,CAAC;;EAEzF,MAAM,eAAe,MAAM,QAAQ,IAAI,OAAO;EAE9C,QAAQ,IAAI,EAAE,8BAA8B,aAAa,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC;EAEtF,IAAI,aAAa,OAAO,SAAS,KAAK,WAAW,MAAM,EACrD,OAAO;GAAE,QAAQ;GAAc,QAAQ,KAAA;GAAW;EAGpD,IAAI;EACJ,IAAI;GACF,SAAS,KAAK,QACX,gBAAgB,aAAa,KAAK,SAAS,KAAK,MAAM,CAAC,CACvD,sBAAsB;GACzB,OAAO;IAAE,QAAQ;IAAM;IAAQ;WACxB,IAAI;GACX,OAAO;IAAE,QAAQ;IAAS,QAAQ,KAAA;IAAW;;;CAIjD,wBACE,cACA,WACA,kBACyB;EACzB,IAAI,UAAU;EACd,QAAQ,KAAK,YAAb;GACE,KAAK;IACH,UAAU,UAAU,KAAK;IACzB;GACF,KAAK;IACH,UAAU,QAAQ,KAAK;IACvB;GACF,KAAK;IACH,UAAU,QAAQ,KAAK,iBAAiB,QAAQ,YAAY,GAAG;IAC/D;GACF,KAAK;IACH,UAAU,YAAY,KAAK;IAC3B;GACF,SACE,MAAM,IAAI,MAAM,sBAAsB;;EAG1C,IAAI,wBAAwB;EAE5B,QAAQ,iBAAiB,aAAa,EAAtC;GACE,KAAK;IACH,wBAAwB,UAAU;IAClC;GACF,KAAK;IACH,wBAAwB,QAAQ;IAChC;GACF,KAAK;IACH,wBAAwB,QAAQ,WAAW,QAAQ,YAAY,GAAG;IAClE;GACF,KAAK;IACH,wBAAwB,YAAY;IACpC;GACF,SACE,MAAM,IAAI,MAAM,8BAA8B;;EAGlD,MAAM,QAAQ;GACZ,oBAAoB;GACpB,gBAAgB;GAChB,WAAW,KAAK,KAAK;GACtB;EAED,OAAO;GACL,QAAQ,KAAK,gBAAgB;GAC7B,OAAO;GACP;GACD;;CAGH,2BACE,iBACA,WACA,qBAC4B;EAC5B,IAAI,UAAU;EACd,QAAQ,KAAK,YAAb;GACE,KAAK;IACH,UAAU,UAAU,KAAK;IACzB;GACF,KAAK;IACH,UAAU,QAAQ,KAAK;IACvB;GACF,KAAK;IACH,UAAU,QAAQ,KAAK,iBAAiB,QAAQ,YAAY,GAAG;IAC/D;GACF,KAAK;IACH,UAAU,YAAY,KAAK;IAC3B;GACF,SACE,MAAM,IAAI,MAAM,sBAAsB;;EAG1C,IAAI,2BAA2B;EAE/B,QAAQ,oBAAoB,aAAa,EAAzC;GACE,KAAK;IACH,2BAA2B,UAAU;IACrC;GACF,KAAK;IACH,2BAA2B,QAAQ;IACnC;GACF,KAAK;IACH,2BAA2B,QAAQ,WAAW,QAAQ,YAAY,GAAG;IACrE;GACF,KAAK;IACH,2BAA2B,YAAY;IACvC;GACF,SACE,MAAM,IAAI,MAAM,iCAAiC;;EAGrD,MAAM,QAAQ;GACZ,oBAAoB;GACpB,mBAAmB;GACnB,WAAW,KAAK,KAAK;GACtB;EACD,OAAO;GACL,QAAQ,KAAK,gBAAgB;GAC7B,OAAO;GACP;GACD;;CAGH,MAAa,WACX,QACA,SACA,WACiB;EACjB,MAAM,gBAAgB,MAAM,KAAK,YAAY;EAC7C,MAAM,WAAW,EAAE;EACnB,KAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;GAC7C,MAAM,eAAe,cAAc;GACnC,SAAS,KAAK,aAAa,eAAe,QAAQ,SAAS,UAAU,CAAC;;EAIxE,KAAI,MAFmB,QAAQ,IAAI,SAAS,EAE/B,OAAO,SAAS,SAAS,MAAM,EAC1C,OAAO;EAGT,OAAO;;CAGT,MAAa,cACX,QACA,SACA,WACiB;EACjB,MAAM,gBAAgB,MAAM,KAAK,YAAY;EAC7C,MAAM,WAAW,EAAE;EACnB,KAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;GAC7C,MAAM,eAAe,cAAc;GACnC,SAAS,KAAK,aAAa,kBAAkB,QAAQ,SAAS,UAAU,CAAC;;EAI3E,KAAI,MAFmB,QAAQ,IAAI,SAAS,EAE/B,OAAO,SAAS,SAAS,MAAM,EAC1C,OAAO;EAGT,OAAO;;CAGT,iBAA0C;EACxC,OAAO;GACL,MAAM;GACN,SAAS;GACT,mBAAmB,KAAK,KAAK,gBAAgB,UAAU,EAAE;GAC1D;;CAGH,MAAc,aAAsC;EAClD,IAAI,KAAK,YAAY,KAAA,GAAW;GAE9B,MAAM,WAAW,MAAM,IADK,mBAAmB,IAAI,cAAc,EAAE,UAAU,KAAK,SAAS,CAAC,CACtD,CAAC,YAAY,EAAE,SAAS,KAAK,iBAAiB,CAAC;GAErF,MAAM,QAAQ,iBAAiB,OAAO,KAAK,SAAS,oBAAqB,SAAS,CAAC;GACnF,KAAK,UAAU,MAAM,MAAM,KACxB,UAAU,IAAI,aAAa,MAAM,UAAU,KAAK,iBAAiB,KAAK,WAAW,CACnF;;EAEH,OAAO,KAAK;;CAGd,OAAe,WAAW,OAAuB;EAC/C,OAAO,OAAO,OAAO,CAAC,eAAe,GAAG,EAAE,MAAM,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"keys-RuC1M-_K.mjs","names":[],"sources":["../src/base.ts","../src/keys.ts"],"sourcesContent":["import type { 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 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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"}
1
+ {"version":3,"file":"keys-RuC1M-_K.mjs","names":[],"sources":["../src/base.ts","../src/keys.ts"],"sourcesContent":["import type { 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 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.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { n as BaseProvider, t as STORAGE_KEYS } from "./keys-RuC1M-_K.mjs";
2
- import { t as Client } from "./client-BSkUuHYm.mjs";
2
+ import { t as Client } from "./client-rcvBXslm.mjs";
3
3
  import { base64Codec, base64Encode, hexDecode, hexEncode, utf8Decode, utf8Encode } from "@idos-network/utils/codecs";
4
4
  import { generatePassword } from "@idos-network/utils/cryptography";
5
5
  import { decrypt, encrypt, keyDerivation } from "@idos-network/utils/encryption";
@@ -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 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,2 +1,2 @@
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-BSkUuHYm.mjs";
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
2
  export { ADD_ADDRESS_TYPES, Client, DOWNLOAD_TYPES, REMOVE_ADDRESS_TYPES, UPDATE_TYPES, UPLOAD_TYPES };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idos-network/enclave",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "idOS Enclave JavaScript SDK",
5
5
  "homepage": "https://idos.network",
6
6
  "license": "MIT",
@@ -34,18 +34,18 @@
34
34
  "scrypt-js": "^3.0.1",
35
35
  "tiny-invariant": "^1.3.3",
36
36
  "tweetnacl": "^1.0.3",
37
- "zod": "4.3.6",
38
- "@idos-network/credentials": "1.1.0",
39
- "@idos-network/utils": "1.1.0",
40
- "@idos-network/kwil-infra": "1.1.0"
37
+ "zod": "4.4.3",
38
+ "@idos-network/credentials": "1.2.0",
39
+ "@idos-network/kwil-infra": "1.2.0",
40
+ "@idos-network/utils": "1.2.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/chrome": "^0.1.0",
44
- "@types/node": "25.5.2",
44
+ "@types/node": "25.6.2",
45
45
  "jsdom": "^22.1.0",
46
- "tsdown": "^0.21.0",
46
+ "tsdown": "^0.22.0",
47
47
  "typescript": "^5.8.3",
48
- "vitest": "4.1.4"
48
+ "vitest": "4.1.5"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "@partisiablockchain/abi-client": "^5.207.0",