@cofhe/sdk 0.7.0 → 0.8.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.
- package/CHANGELOG.md +37 -0
- package/acps/acp.ts +10 -1
- package/acps/index.ts +11 -0
- package/acps/onchain-utils.ts +188 -49
- package/acps/registry.ts +73 -0
- package/acps/test/onchainAccessStatus.test.ts +116 -0
- package/acps/types.ts +16 -0
- package/chains/chains/arbitrum.ts +14 -0
- package/chains/chains/ethereum.ts +14 -0
- package/chains/index.ts +5 -1
- package/chains/test/chains.test.ts +24 -3
- package/core/acps.ts +51 -143
- package/core/client.ts +13 -8
- package/core/clientTypes.ts +29 -4
- package/core/config.ts +25 -1
- package/core/consts.ts +14 -2
- package/core/decrypt/verifyDecryptResult.ts +4 -3
- package/core/encrypt/encryptInputsBuilder.ts +6 -0
- package/core/encrypt/zkPackProveVerify.ts +7 -1
- package/core/error.ts +1 -0
- package/core/fetchKeys.ts +2 -2
- package/core/index.ts +9 -1
- package/core/keyStore.ts +23 -10
- package/core/taskManager.ts +48 -0
- package/core/test/acps.test.ts +91 -1
- package/core/test/client.test.ts +41 -0
- package/core/test/config.test.ts +16 -0
- package/core/test/decrypt.test.ts +11 -4
- package/core/test/encryptInputsBuilder.test.ts +1 -1
- package/core/test/fetchKeys.test.ts +23 -2
- package/core/test/keyStore.test.ts +18 -6
- package/core/test/taskManager.test.ts +57 -0
- package/core/types.ts +8 -0
- package/dist/acps.cjs +314 -35
- package/dist/acps.d.cts +251 -4
- package/dist/acps.d.ts +251 -4
- package/dist/acps.js +2 -2
- package/dist/chains.cjs +26 -0
- package/dist/chains.d.cts +45 -1
- package/dist/chains.d.ts +45 -1
- package/dist/chains.js +1 -1
- package/dist/{chunk-43USWPEH.js → chunk-GGI7Y6AW.js} +59 -264
- package/dist/chunk-KSOV5B4B.js +50 -0
- package/dist/{chunk-ESMZCFJY.js → chunk-NMKMCAI3.js} +4 -2
- package/dist/{chunk-Q7CBWGQX.js → chunk-UJYOBHYA.js} +374 -37
- package/dist/{chunk-N6IDQRRU.js → chunk-UKQAJK4N.js} +25 -1
- package/dist/{clientTypes-BN3nbzYM.d.ts → clientTypes-5YPPR16m.d.ts} +77 -14
- package/dist/{clientTypes-CYZjFznO.d.cts → clientTypes-D3aIXmUp.d.cts} +77 -14
- package/dist/core.cjs +271 -136
- package/dist/core.d.cts +29 -8
- package/dist/core.d.ts +29 -8
- package/dist/core.js +4 -4
- package/dist/node.cjs +266 -136
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +5 -5
- package/dist/{acp-Wi6isVQI.d.cts → onchain-utils-CUAK8glx.d.cts} +31 -1
- package/dist/{acp-Wi6isVQI.d.ts → onchain-utils-CUAK8glx.d.ts} +31 -1
- package/dist/web.cjs +360 -150
- package/dist/web.d.cts +49 -3
- package/dist/web.d.ts +49 -3
- package/dist/web.js +51 -20
- package/dist/zkProve.worker.cjs +69 -15
- package/dist/zkProve.worker.js +23 -17
- package/node/storage.ts +2 -2
- package/node/test/inherited.test.ts +5 -1
- package/node/test/storage-memory-fallback.test.ts +47 -0
- package/package.json +5 -3
- package/web/index.ts +100 -26
- package/web/test/countingZkProveWorker.ts +31 -0
- package/web/test/inherited.web.test.ts +5 -1
- package/web/test/mainThreadPool.web.test.ts +174 -0
- package/web/test/threadPoolBenchHelper.ts +140 -0
- package/web/test/threadPoolOff.web.test.ts +17 -0
- package/web/test/threadPoolOn.web.test.ts +80 -0
- package/web/test/workerInitRace.web.test.ts +79 -0
- package/web/tfheThreadPool.ts +140 -0
- package/web/workerManager.ts +4 -2
- package/web/zkProve.worker.ts +42 -17
package/dist/web.cjs
CHANGED
|
@@ -112,7 +112,8 @@ var bigintSafeJsonStringify = (value) => {
|
|
|
112
112
|
var isCofheError = (error) => error instanceof CofheError;
|
|
113
113
|
|
|
114
114
|
// core/consts.ts
|
|
115
|
-
var
|
|
115
|
+
var COFHE_ADDRESS_BOOK_ADDRESS = "0xC0F4e00E531a2B086492Ae3DCC1515038307196b";
|
|
116
|
+
var TASK_MANAGER_ID = 1n;
|
|
116
117
|
var MOCKS_ZK_VERIFIER_ADDRESS = "0x0000000000000000000000000000000000005001";
|
|
117
118
|
var MOCKS_THRESHOLD_NETWORK_ADDRESS = "0x0000000000000000000000000000000000005002";
|
|
118
119
|
var MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = "0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512";
|
|
@@ -748,6 +749,8 @@ var CofheConfigSchema = zod.z.object({
|
|
|
748
749
|
}).or(zod.z.null()).default(null),
|
|
749
750
|
/** Whether to use Web Workers for ZK proof generation (web platform only) */
|
|
750
751
|
useWorkers: zod.z.boolean().optional().default(true),
|
|
752
|
+
/** How many threads tfhe's rayon pool may use for ZK proof generation (web platform only) */
|
|
753
|
+
tfheThreads: zod.z.union([zod.z.number().int().positive(), zod.z.literal("auto"), zod.z.literal(false)]).optional().default("auto"),
|
|
751
754
|
/** ACP acp defaults */
|
|
752
755
|
acp: zod.z.object({
|
|
753
756
|
defaultRevoker: zod.z.custom().optional(),
|
|
@@ -853,6 +856,9 @@ var DEFAULT_KEYS_STORE = {
|
|
|
853
856
|
fhe: {},
|
|
854
857
|
crs: {}
|
|
855
858
|
};
|
|
859
|
+
function isSecurityZoneRecord(value) {
|
|
860
|
+
return value != null && typeof value === "object";
|
|
861
|
+
}
|
|
856
862
|
function isStoreWithPersist(store) {
|
|
857
863
|
return "persist" in store;
|
|
858
864
|
}
|
|
@@ -867,10 +873,10 @@ function createKeysStore(storage) {
|
|
|
867
873
|
const stored = keysStore.getState().fhe[chainId]?.[securityZone];
|
|
868
874
|
return stored;
|
|
869
875
|
};
|
|
870
|
-
const getCrs = (chainId) => {
|
|
871
|
-
if (chainId == null)
|
|
876
|
+
const getCrs = (chainId, securityZone = 0) => {
|
|
877
|
+
if (chainId == null || securityZone == null)
|
|
872
878
|
return void 0;
|
|
873
|
-
const stored = keysStore.getState().crs[chainId];
|
|
879
|
+
const stored = keysStore.getState().crs[chainId]?.[securityZone];
|
|
874
880
|
return stored;
|
|
875
881
|
};
|
|
876
882
|
const setFheKey = (chainId, securityZone, key) => {
|
|
@@ -882,10 +888,12 @@ function createKeysStore(storage) {
|
|
|
882
888
|
})
|
|
883
889
|
);
|
|
884
890
|
};
|
|
885
|
-
const setCrs = (chainId, crs) => {
|
|
891
|
+
const setCrs = (chainId, securityZone, crs) => {
|
|
886
892
|
keysStore.setState(
|
|
887
893
|
immer.produce((state) => {
|
|
888
|
-
state.crs[chainId]
|
|
894
|
+
if (state.crs[chainId] == null)
|
|
895
|
+
state.crs[chainId] = {};
|
|
896
|
+
state.crs[chainId][securityZone] = crs;
|
|
889
897
|
})
|
|
890
898
|
);
|
|
891
899
|
};
|
|
@@ -933,7 +941,13 @@ function createStoreWithPersit(storage) {
|
|
|
933
941
|
const currentZones = current.fhe[chainId] || {};
|
|
934
942
|
mergedFhe[chainId] = { ...persistedZones, ...currentZones };
|
|
935
943
|
}
|
|
936
|
-
const mergedCrs = {
|
|
944
|
+
const mergedCrs = {};
|
|
945
|
+
const allCrsChainIds = /* @__PURE__ */ new Set([...Object.keys(current.crs), ...Object.keys(persisted.crs)]);
|
|
946
|
+
for (const chainId of allCrsChainIds) {
|
|
947
|
+
const persistedZones = isSecurityZoneRecord(persisted.crs[chainId]) ? persisted.crs[chainId] : {};
|
|
948
|
+
const currentZones = isSecurityZoneRecord(current.crs[chainId]) ? current.crs[chainId] : {};
|
|
949
|
+
mergedCrs[chainId] = { ...persistedZones, ...currentZones };
|
|
950
|
+
}
|
|
937
951
|
return {
|
|
938
952
|
fhe: mergedFhe,
|
|
939
953
|
crs: mergedCrs
|
|
@@ -995,7 +1009,7 @@ var fetchFhePublicKey = async (coFheUrl, chainId, securityZone, tfhePublicKeyDes
|
|
|
995
1009
|
return [pk_data, true];
|
|
996
1010
|
};
|
|
997
1011
|
var fetchCrs = async (coFheUrl, chainId, securityZone, compactPkeCrsDeserializer2, keysStorage) => {
|
|
998
|
-
const storedKey = keysStorage?.getCrs(chainId);
|
|
1012
|
+
const storedKey = keysStorage?.getCrs(chainId, securityZone);
|
|
999
1013
|
const [storedKeyValid] = checkKeyValidity(storedKey, compactPkeCrsDeserializer2);
|
|
1000
1014
|
if (storedKeyValid)
|
|
1001
1015
|
return [storedKey, false];
|
|
@@ -1022,7 +1036,7 @@ var fetchCrs = async (coFheUrl, chainId, securityZone, compactPkeCrsDeserializer
|
|
|
1022
1036
|
console.error(`Error serializing CRS ${err}`);
|
|
1023
1037
|
throw new Error(`Error serializing CRS; ${err}`);
|
|
1024
1038
|
}
|
|
1025
|
-
keysStorage?.setCrs(chainId, crs_data);
|
|
1039
|
+
keysStorage?.setCrs(chainId, securityZone, crs_data);
|
|
1026
1040
|
return [crs_data, true];
|
|
1027
1041
|
};
|
|
1028
1042
|
var fetchKeys = async (config, chainId, securityZone = 0, tfhePublicKeyDeserializer2, compactPkeCrsDeserializer2, keysStorage) => {
|
|
@@ -1134,6 +1148,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1134
1148
|
zkBuilderAndCrsGenerator;
|
|
1135
1149
|
initTfhe;
|
|
1136
1150
|
zkProveWorkerFn;
|
|
1151
|
+
beforeMainThreadProve;
|
|
1137
1152
|
keysStorage;
|
|
1138
1153
|
// Worker configuration (from config, overrideable)
|
|
1139
1154
|
useWorker;
|
|
@@ -1191,6 +1206,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1191
1206
|
this.zkBuilderAndCrsGenerator = params.zkBuilderAndCrsGenerator;
|
|
1192
1207
|
this.initTfhe = params.initTfhe;
|
|
1193
1208
|
this.zkProveWorkerFn = params.zkProveWorkerFn;
|
|
1209
|
+
this.beforeMainThreadProve = params.beforeMainThreadProve;
|
|
1194
1210
|
this.keysStorage = params.keysStorage;
|
|
1195
1211
|
this.useWorker = params.config?.useWorkers ?? true;
|
|
1196
1212
|
}
|
|
@@ -1481,6 +1497,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1481
1497
|
}
|
|
1482
1498
|
}
|
|
1483
1499
|
if (proof == null) {
|
|
1500
|
+
await this.beforeMainThreadProve?.();
|
|
1484
1501
|
proof = await zkProve(zkBuilder, zkCrs, metadata);
|
|
1485
1502
|
usedWorker = false;
|
|
1486
1503
|
}
|
|
@@ -1877,11 +1894,40 @@ var SignatureUtils = {
|
|
|
1877
1894
|
throw new Error(`Unknown acp type: ${acpType}`);
|
|
1878
1895
|
}
|
|
1879
1896
|
};
|
|
1897
|
+
var ADDRESS_BOOK_ABI = viem.parseAbi([
|
|
1898
|
+
"function getTm(uint256 id) view returns (address)",
|
|
1899
|
+
"error TaskManagerNotSet(uint256 id)"
|
|
1900
|
+
]);
|
|
1901
|
+
var taskManagerAddressCache = /* @__PURE__ */ new Map();
|
|
1902
|
+
var getTaskManagerAddress = async (publicClient, chainId) => {
|
|
1903
|
+
const id = chainId ?? publicClient.chain?.id ?? await publicClient.getChainId();
|
|
1904
|
+
const cached = taskManagerAddressCache.get(id);
|
|
1905
|
+
if (cached != null)
|
|
1906
|
+
return cached;
|
|
1907
|
+
const pending = publicClient.readContract({
|
|
1908
|
+
address: COFHE_ADDRESS_BOOK_ADDRESS,
|
|
1909
|
+
abi: ADDRESS_BOOK_ABI,
|
|
1910
|
+
functionName: "getTm",
|
|
1911
|
+
args: [TASK_MANAGER_ID]
|
|
1912
|
+
}).catch((error) => {
|
|
1913
|
+
taskManagerAddressCache.delete(id);
|
|
1914
|
+
throw CofheError.fromError(error, {
|
|
1915
|
+
code: "TASK_MANAGER_UNRESOLVED" /* TaskManagerUnresolved */,
|
|
1916
|
+
message: `Failed to resolve the Task Manager from the CoFHEAddressBook on chain ${id}`,
|
|
1917
|
+
hint: "Ensure CoFHE is deployed on this chain. On a local hardhat / anvil chain, deploy the CoFHE mocks first.",
|
|
1918
|
+
context: { chainId: id, addressBook: COFHE_ADDRESS_BOOK_ADDRESS, taskManagerId: TASK_MANAGER_ID }
|
|
1919
|
+
});
|
|
1920
|
+
});
|
|
1921
|
+
taskManagerAddressCache.set(id, pending);
|
|
1922
|
+
return pending;
|
|
1923
|
+
};
|
|
1924
|
+
|
|
1925
|
+
// acps/onchain-utils.ts
|
|
1880
1926
|
var getAclAddress = async (publicClient) => {
|
|
1881
1927
|
const ACL_IFACE = "function acl() view returns (address)";
|
|
1882
1928
|
const aclAbi = viem.parseAbi([ACL_IFACE]);
|
|
1883
1929
|
return await publicClient.readContract({
|
|
1884
|
-
address:
|
|
1930
|
+
address: await getTaskManagerAddress(publicClient),
|
|
1885
1931
|
abi: aclAbi,
|
|
1886
1932
|
functionName: "acl"
|
|
1887
1933
|
});
|
|
@@ -1908,6 +1954,34 @@ var getAclEIP712Domain = async (publicClient) => {
|
|
|
1908
1954
|
verifyingContract
|
|
1909
1955
|
};
|
|
1910
1956
|
};
|
|
1957
|
+
var toACPTuple = (acp) => ({
|
|
1958
|
+
issuer: acp.issuer,
|
|
1959
|
+
expiration: BigInt(acp.expiration),
|
|
1960
|
+
recipient: acp.recipient,
|
|
1961
|
+
revokerData: BigInt(acp.revokerData),
|
|
1962
|
+
revokerContract: acp.revokerContract,
|
|
1963
|
+
scope: acp.scope,
|
|
1964
|
+
contracts: acp.contracts,
|
|
1965
|
+
handles: acp.handles,
|
|
1966
|
+
sealingKey: acp.sealingKey,
|
|
1967
|
+
issuerSignature: acp.issuerSignature,
|
|
1968
|
+
recipientSignature: acp.recipientSignature
|
|
1969
|
+
});
|
|
1970
|
+
function revertErrorName(err, abi) {
|
|
1971
|
+
const walk = err?.walk;
|
|
1972
|
+
if (typeof walk === "function") {
|
|
1973
|
+
const revertError = walk.call(err, (e) => e?.name === "ContractFunctionRevertedError");
|
|
1974
|
+
if (revertError)
|
|
1975
|
+
return revertError.data?.errorName ?? "";
|
|
1976
|
+
}
|
|
1977
|
+
const customErrorName = extractCustomErrorFromDetails(err, abi);
|
|
1978
|
+
if (customErrorName)
|
|
1979
|
+
return customErrorName;
|
|
1980
|
+
const hhDetailsData = extractReturnData(err);
|
|
1981
|
+
if (hhDetailsData != null)
|
|
1982
|
+
return viem.decodeErrorResult({ abi, data: hhDetailsData }).errorName;
|
|
1983
|
+
return void 0;
|
|
1984
|
+
}
|
|
1911
1985
|
var checkACPValidityOnChain = async (acp, publicClient) => {
|
|
1912
1986
|
const aclAddress = await getAclAddress(publicClient);
|
|
1913
1987
|
try {
|
|
@@ -1915,43 +1989,54 @@ var checkACPValidityOnChain = async (acp, publicClient) => {
|
|
|
1915
1989
|
address: aclAddress,
|
|
1916
1990
|
abi: checkACPValidityAbi,
|
|
1917
1991
|
functionName: "checkPermissionValidity",
|
|
1918
|
-
args: [
|
|
1919
|
-
{
|
|
1920
|
-
issuer: acp.issuer,
|
|
1921
|
-
expiration: BigInt(acp.expiration),
|
|
1922
|
-
recipient: acp.recipient,
|
|
1923
|
-
revokerData: BigInt(acp.revokerData),
|
|
1924
|
-
revokerContract: acp.revokerContract,
|
|
1925
|
-
scope: acp.scope,
|
|
1926
|
-
contracts: acp.contracts,
|
|
1927
|
-
handles: acp.handles,
|
|
1928
|
-
sealingKey: acp.sealingKey,
|
|
1929
|
-
issuerSignature: acp.issuerSignature,
|
|
1930
|
-
recipientSignature: acp.recipientSignature
|
|
1931
|
-
}
|
|
1932
|
-
]
|
|
1992
|
+
args: [toACPTuple(acp)]
|
|
1933
1993
|
});
|
|
1934
1994
|
return true;
|
|
1935
1995
|
} catch (err) {
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1996
|
+
const errorName = revertErrorName(err, checkACPValidityAbi);
|
|
1997
|
+
if (errorName !== void 0)
|
|
1998
|
+
throw new Error(errorName);
|
|
1999
|
+
throw err;
|
|
2000
|
+
}
|
|
2001
|
+
};
|
|
2002
|
+
var PERMISSION_ERROR_STATUS = {
|
|
2003
|
+
PermissionInvalid_Expired: "expired",
|
|
2004
|
+
PermissionInvalid_Disabled: "revoked",
|
|
2005
|
+
PermissionInvalid_IssuerSignature: "invalid-issuer-signature",
|
|
2006
|
+
PermissionInvalid_RecipientSignature: "invalid-recipient-signature"
|
|
2007
|
+
};
|
|
2008
|
+
var getACPAccessStatusOnChain = async (acp, publicClient, handle) => {
|
|
2009
|
+
const aclAddress = await getAclAddress(publicClient);
|
|
2010
|
+
try {
|
|
2011
|
+
if (handle === void 0) {
|
|
2012
|
+
await publicClient.simulateContract({
|
|
2013
|
+
address: aclAddress,
|
|
2014
|
+
abi: acpAccessAbi,
|
|
2015
|
+
functionName: "checkPermissionValidity",
|
|
2016
|
+
args: [toACPTuple(acp)]
|
|
1952
2017
|
});
|
|
1953
|
-
|
|
2018
|
+
return "valid";
|
|
1954
2019
|
}
|
|
2020
|
+
const ctHash = BigInt(handle);
|
|
2021
|
+
const allowed = await publicClient.readContract({
|
|
2022
|
+
address: aclAddress,
|
|
2023
|
+
abi: acpAccessAbi,
|
|
2024
|
+
functionName: "isAllowedWithPermission",
|
|
2025
|
+
args: [toACPTuple(acp), ctHash]
|
|
2026
|
+
});
|
|
2027
|
+
if (allowed)
|
|
2028
|
+
return "allowed";
|
|
2029
|
+
const issuerAllowed = await publicClient.readContract({
|
|
2030
|
+
address: aclAddress,
|
|
2031
|
+
abi: acpAccessAbi,
|
|
2032
|
+
functionName: "isAllowed",
|
|
2033
|
+
args: [ctHash, acp.issuer]
|
|
2034
|
+
});
|
|
2035
|
+
return issuerAllowed ? "out-of-scope" : "issuer-not-allowed";
|
|
2036
|
+
} catch (err) {
|
|
2037
|
+
const status = PERMISSION_ERROR_STATUS[revertErrorName(err, acpAccessAbi) ?? ""];
|
|
2038
|
+
if (status)
|
|
2039
|
+
return status;
|
|
1955
2040
|
throw err;
|
|
1956
2041
|
}
|
|
1957
2042
|
};
|
|
@@ -1973,7 +2058,8 @@ function extractCustomErrorFromDetails(err, abi) {
|
|
|
1973
2058
|
function extractReturnData(err) {
|
|
1974
2059
|
const anyErr = err;
|
|
1975
2060
|
const s = anyErr?.details ?? anyErr?.cause?.details ?? anyErr?.shortMessage ?? anyErr?.message ?? String(err);
|
|
1976
|
-
|
|
2061
|
+
const match = s.match(/return data:\s*(0x[a-fA-F0-9]+)/) ?? s.match(/custom error (0x[a-fA-F0-9]{8,})/);
|
|
2062
|
+
return match?.[1];
|
|
1977
2063
|
}
|
|
1978
2064
|
var checkACPValidityAbi = [
|
|
1979
2065
|
{
|
|
@@ -2073,6 +2159,58 @@ var checkACPValidityAbi = [
|
|
|
2073
2159
|
inputs: []
|
|
2074
2160
|
}
|
|
2075
2161
|
];
|
|
2162
|
+
var acpAccessAbi = [
|
|
2163
|
+
...checkACPValidityAbi,
|
|
2164
|
+
{
|
|
2165
|
+
type: "function",
|
|
2166
|
+
name: "isAllowedWithPermission",
|
|
2167
|
+
inputs: [checkACPValidityAbi[0].inputs[0], { name: "handle", type: "uint256", internalType: "uint256" }],
|
|
2168
|
+
outputs: [{ name: "", type: "bool", internalType: "bool" }],
|
|
2169
|
+
stateMutability: "view"
|
|
2170
|
+
},
|
|
2171
|
+
{
|
|
2172
|
+
type: "function",
|
|
2173
|
+
name: "isAllowed",
|
|
2174
|
+
inputs: [
|
|
2175
|
+
{ name: "handle", type: "uint256", internalType: "uint256" },
|
|
2176
|
+
{ name: "account", type: "address", internalType: "address" }
|
|
2177
|
+
],
|
|
2178
|
+
outputs: [{ name: "", type: "bool", internalType: "bool" }],
|
|
2179
|
+
stateMutability: "view"
|
|
2180
|
+
}
|
|
2181
|
+
];
|
|
2182
|
+
var ACL_SERVED_ADDRESSES_ABI = viem.parseAbi([
|
|
2183
|
+
"function acl() view returns (address)",
|
|
2184
|
+
"function defaultRevokerContract() view returns (address)",
|
|
2185
|
+
"function shareRegistry() view returns (address)"
|
|
2186
|
+
]);
|
|
2187
|
+
var aclServedAddressesCache = /* @__PURE__ */ new Map();
|
|
2188
|
+
var clearAclServedAddresses = () => aclServedAddressesCache.clear();
|
|
2189
|
+
var getAclServedAddresses = async (publicClient, chainId) => {
|
|
2190
|
+
const cached = aclServedAddressesCache.get(chainId);
|
|
2191
|
+
if (cached != null)
|
|
2192
|
+
return cached;
|
|
2193
|
+
let aclAddress;
|
|
2194
|
+
try {
|
|
2195
|
+
aclAddress = await publicClient.readContract({
|
|
2196
|
+
address: await getTaskManagerAddress(publicClient, chainId),
|
|
2197
|
+
abi: ACL_SERVED_ADDRESSES_ABI,
|
|
2198
|
+
functionName: "acl"
|
|
2199
|
+
});
|
|
2200
|
+
} catch {
|
|
2201
|
+
return {};
|
|
2202
|
+
}
|
|
2203
|
+
const [defaultRevoker, shareRegistry] = await Promise.all([
|
|
2204
|
+
publicClient.readContract({ address: aclAddress, abi: ACL_SERVED_ADDRESSES_ABI, functionName: "defaultRevokerContract" }).catch(() => void 0),
|
|
2205
|
+
publicClient.readContract({ address: aclAddress, abi: ACL_SERVED_ADDRESSES_ABI, functionName: "shareRegistry" }).catch(() => void 0)
|
|
2206
|
+
]);
|
|
2207
|
+
const resolved = {
|
|
2208
|
+
defaultRevoker: defaultRevoker != null && defaultRevoker !== viem.zeroAddress ? defaultRevoker : void 0,
|
|
2209
|
+
shareRegistry: shareRegistry != null && shareRegistry !== viem.zeroAddress ? shareRegistry : void 0
|
|
2210
|
+
};
|
|
2211
|
+
aclServedAddressesCache.set(chainId, resolved);
|
|
2212
|
+
return resolved;
|
|
2213
|
+
};
|
|
2076
2214
|
|
|
2077
2215
|
// acps/acp.ts
|
|
2078
2216
|
var ACPUtils = {
|
|
@@ -2386,8 +2524,62 @@ var ACPUtils = {
|
|
|
2386
2524
|
checkValidityOnChain: async (acp, publicClient) => {
|
|
2387
2525
|
const publicAcp = ACPUtils.getPublic(acp);
|
|
2388
2526
|
return checkACPValidityOnChain(publicAcp, publicClient);
|
|
2527
|
+
},
|
|
2528
|
+
/**
|
|
2529
|
+
* The acp on-chain status as a value instead of a revert: 'valid' or why not, and given a
|
|
2530
|
+
* handle, whether the acp may read it (see `ACPAccessStatus`).
|
|
2531
|
+
*/
|
|
2532
|
+
checkAccessOnChain: async (acp, publicClient, handle) => {
|
|
2533
|
+
return getACPAccessStatusOnChain(ACPUtils.getPublic(acp), publicClient, handle);
|
|
2389
2534
|
}
|
|
2390
2535
|
};
|
|
2536
|
+
var ACP_REVOKER_ABI = viem.parseAbi([
|
|
2537
|
+
"function revokeSingle(uint256 id)",
|
|
2538
|
+
"function revokeAllExisting()",
|
|
2539
|
+
"function disabled(address issuer, uint256 id) view returns (bool)"
|
|
2540
|
+
]);
|
|
2541
|
+
var ACP_SHARE_REGISTRY_ABI = viem.parseAbi([
|
|
2542
|
+
"struct ACP { address issuer; uint64 expiration; address recipient; uint256 revokerData; address revokerContract; uint8 scope; address[] contracts; bytes32[] handles; bytes32 sealingKey; bytes issuerSignature; bytes recipientSignature; }",
|
|
2543
|
+
"function share(ACP calldata acp) external returns (bytes32)",
|
|
2544
|
+
"function removeShare(bytes32 shareId) external",
|
|
2545
|
+
"function sharesFor(address recipient) external view returns (ACP[] memory)",
|
|
2546
|
+
"function getShare(bytes32 shareId) external view returns (ACP memory)",
|
|
2547
|
+
"function isShareValid(bytes32 shareId) external view returns (bool)"
|
|
2548
|
+
]);
|
|
2549
|
+
var ACP_SHARE_TUPLE_ABI = [
|
|
2550
|
+
{
|
|
2551
|
+
type: "tuple",
|
|
2552
|
+
components: [
|
|
2553
|
+
{ name: "issuer", type: "address" },
|
|
2554
|
+
{ name: "expiration", type: "uint64" },
|
|
2555
|
+
{ name: "recipient", type: "address" },
|
|
2556
|
+
{ name: "revokerData", type: "uint256" },
|
|
2557
|
+
{ name: "revokerContract", type: "address" },
|
|
2558
|
+
{ name: "scope", type: "uint8" },
|
|
2559
|
+
{ name: "contracts", type: "address[]" },
|
|
2560
|
+
{ name: "handles", type: "bytes32[]" },
|
|
2561
|
+
{ name: "sealingKey", type: "bytes32" },
|
|
2562
|
+
{ name: "issuerSignature", type: "bytes" },
|
|
2563
|
+
{ name: "recipientSignature", type: "bytes" }
|
|
2564
|
+
]
|
|
2565
|
+
}
|
|
2566
|
+
];
|
|
2567
|
+
var ZERO_BYTES32 = `0x${"0".repeat(64)}`;
|
|
2568
|
+
var toChainShare = (acp) => {
|
|
2569
|
+
const pub = ACPUtils.getPublic(acp, true);
|
|
2570
|
+
return {
|
|
2571
|
+
...pub,
|
|
2572
|
+
expiration: BigInt(pub.expiration),
|
|
2573
|
+
revokerData: BigInt(pub.revokerData),
|
|
2574
|
+
sealingKey: ZERO_BYTES32,
|
|
2575
|
+
recipientSignature: "0x"
|
|
2576
|
+
};
|
|
2577
|
+
};
|
|
2578
|
+
var computeShareId = (acp) => {
|
|
2579
|
+
const p = toChainShare(acp);
|
|
2580
|
+
return viem.keccak256(viem.encodeAbiParameters(ACP_SHARE_TUPLE_ABI, [p]));
|
|
2581
|
+
};
|
|
2582
|
+
var shareIdOfChainShare = (share) => viem.keccak256(viem.encodeAbiParameters(ACP_SHARE_TUPLE_ABI, [share]));
|
|
2391
2583
|
var ACP_STORE_DEFAULTS = {
|
|
2392
2584
|
acps: {},
|
|
2393
2585
|
activeACPHash: {}
|
|
@@ -2513,11 +2705,6 @@ var acpStore = {
|
|
|
2513
2705
|
removeActiveACPHash,
|
|
2514
2706
|
resetStore
|
|
2515
2707
|
};
|
|
2516
|
-
var ACP_VALIDATOR_ABI = viem.parseAbi([
|
|
2517
|
-
"function revokeSingle(uint256 id)",
|
|
2518
|
-
"function revokeAllExisting()",
|
|
2519
|
-
"function disabled(address issuer, uint256 id) view returns (bool)"
|
|
2520
|
-
]);
|
|
2521
2708
|
var storeACP = async (acp, publicClient, walletClient) => {
|
|
2522
2709
|
const chainId = await publicClient.getChainId();
|
|
2523
2710
|
const account = walletClient.account.address;
|
|
@@ -2544,8 +2731,8 @@ var createSelf = async (options, publicClient, walletClient) => {
|
|
|
2544
2731
|
var createSharing = async (options, publicClient, walletClient) => {
|
|
2545
2732
|
return createACPWithSign(options, publicClient, walletClient, ACPUtils.createSharingAndSign, false);
|
|
2546
2733
|
};
|
|
2547
|
-
var importShared = async (options, publicClient, walletClient) => {
|
|
2548
|
-
return createACPWithSign(options, publicClient, walletClient, ACPUtils.importSharedAndSign);
|
|
2734
|
+
var importShared = async (options, publicClient, walletClient, { activate = true } = {}) => {
|
|
2735
|
+
return createACPWithSign(options, publicClient, walletClient, ACPUtils.importSharedAndSign, activate);
|
|
2549
2736
|
};
|
|
2550
2737
|
var getHash = (acp) => {
|
|
2551
2738
|
return ACPUtils.getHash(acp);
|
|
@@ -2607,38 +2794,6 @@ var applyACPDefaults = (options, acpConfig, chainId) => {
|
|
|
2607
2794
|
}
|
|
2608
2795
|
return result;
|
|
2609
2796
|
};
|
|
2610
|
-
var ACL_SERVED_ADDRESSES_ABI = viem.parseAbi([
|
|
2611
|
-
"function acl() view returns (address)",
|
|
2612
|
-
"function defaultRevokerContract() view returns (address)",
|
|
2613
|
-
"function shareRegistry() view returns (address)"
|
|
2614
|
-
]);
|
|
2615
|
-
var aclServedAddressesCache = /* @__PURE__ */ new Map();
|
|
2616
|
-
var clearAclServedAddresses = () => aclServedAddressesCache.clear();
|
|
2617
|
-
var getAclServedAddresses = async (publicClient, chainId) => {
|
|
2618
|
-
const cached = aclServedAddressesCache.get(chainId);
|
|
2619
|
-
if (cached != null)
|
|
2620
|
-
return cached;
|
|
2621
|
-
let aclAddress;
|
|
2622
|
-
try {
|
|
2623
|
-
aclAddress = await publicClient.readContract({
|
|
2624
|
-
address: TASK_MANAGER_ADDRESS,
|
|
2625
|
-
abi: ACL_SERVED_ADDRESSES_ABI,
|
|
2626
|
-
functionName: "acl"
|
|
2627
|
-
});
|
|
2628
|
-
} catch {
|
|
2629
|
-
return {};
|
|
2630
|
-
}
|
|
2631
|
-
const [defaultRevoker, shareRegistry] = await Promise.all([
|
|
2632
|
-
publicClient.readContract({ address: aclAddress, abi: ACL_SERVED_ADDRESSES_ABI, functionName: "defaultRevokerContract" }).catch(() => void 0),
|
|
2633
|
-
publicClient.readContract({ address: aclAddress, abi: ACL_SERVED_ADDRESSES_ABI, functionName: "shareRegistry" }).catch(() => void 0)
|
|
2634
|
-
]);
|
|
2635
|
-
const resolved = {
|
|
2636
|
-
defaultRevoker: defaultRevoker != null && defaultRevoker !== viem.zeroAddress ? defaultRevoker : void 0,
|
|
2637
|
-
shareRegistry: shareRegistry != null && shareRegistry !== viem.zeroAddress ? shareRegistry : void 0
|
|
2638
|
-
};
|
|
2639
|
-
aclServedAddressesCache.set(chainId, resolved);
|
|
2640
|
-
return resolved;
|
|
2641
|
-
};
|
|
2642
2797
|
var applyACPDefaultsFromChain = async (options, acpConfig, publicClient, chainId) => {
|
|
2643
2798
|
const hasExplicitRevoker = acpConfig?.defaultRevoker?.[chainId] != null || options.revokerData != null || options.revokerContract != null;
|
|
2644
2799
|
if (hasExplicitRevoker)
|
|
@@ -2658,7 +2813,7 @@ var revokeACP = async (acp, walletClient) => {
|
|
|
2658
2813
|
}
|
|
2659
2814
|
return walletClient.writeContract({
|
|
2660
2815
|
address: acp.revokerContract,
|
|
2661
|
-
abi:
|
|
2816
|
+
abi: ACP_REVOKER_ABI,
|
|
2662
2817
|
functionName: "revokeSingle",
|
|
2663
2818
|
args: [BigInt(acp.revokerData)],
|
|
2664
2819
|
account: walletClient.account,
|
|
@@ -2679,64 +2834,31 @@ var revokeAllACPs = async (walletClient, publicClient, revokerContract) => {
|
|
|
2679
2834
|
}
|
|
2680
2835
|
return walletClient.writeContract({
|
|
2681
2836
|
address: revoker,
|
|
2682
|
-
abi:
|
|
2837
|
+
abi: ACP_REVOKER_ABI,
|
|
2683
2838
|
functionName: "revokeAllExisting",
|
|
2684
2839
|
args: [],
|
|
2685
2840
|
account: walletClient.account,
|
|
2686
2841
|
chain: walletClient.chain
|
|
2687
2842
|
});
|
|
2688
2843
|
};
|
|
2844
|
+
var checkAccess = async (acp, publicClient, handle) => {
|
|
2845
|
+
if (acp.type === "sharing" && handle === void 0) {
|
|
2846
|
+
if (ACPUtils.isExpired(acp))
|
|
2847
|
+
return "expired";
|
|
2848
|
+
return await isACPRevoked(acp, publicClient) ? "revoked" : "valid";
|
|
2849
|
+
}
|
|
2850
|
+
return ACPUtils.checkAccessOnChain(acp, publicClient, handle);
|
|
2851
|
+
};
|
|
2689
2852
|
var isACPRevoked = async (acp, publicClient) => {
|
|
2690
2853
|
if (acp.revokerContract === viem.zeroAddress || acp.revokerData === 0)
|
|
2691
2854
|
return false;
|
|
2692
2855
|
return publicClient.readContract({
|
|
2693
2856
|
address: acp.revokerContract,
|
|
2694
|
-
abi:
|
|
2857
|
+
abi: ACP_REVOKER_ABI,
|
|
2695
2858
|
functionName: "disabled",
|
|
2696
2859
|
args: [acp.issuer, BigInt(acp.revokerData)]
|
|
2697
2860
|
});
|
|
2698
2861
|
};
|
|
2699
|
-
var ACP_SHARE_REGISTRY_ABI = viem.parseAbi([
|
|
2700
|
-
"struct ACP { address issuer; uint64 expiration; address recipient; uint256 revokerData; address revokerContract; uint8 scope; address[] contracts; bytes32[] handles; bytes32 sealingKey; bytes issuerSignature; bytes recipientSignature; }",
|
|
2701
|
-
"function share(ACP calldata acp) external returns (bytes32)",
|
|
2702
|
-
"function removeShare(bytes32 shareId) external",
|
|
2703
|
-
"function sharesFor(address recipient) external view returns (ACP[] memory)",
|
|
2704
|
-
"function getShare(bytes32 shareId) external view returns (ACP memory)",
|
|
2705
|
-
"function isShareValid(bytes32 shareId) external view returns (bool)"
|
|
2706
|
-
]);
|
|
2707
|
-
var ACP_TUPLE = [
|
|
2708
|
-
{
|
|
2709
|
-
type: "tuple",
|
|
2710
|
-
components: [
|
|
2711
|
-
{ name: "issuer", type: "address" },
|
|
2712
|
-
{ name: "expiration", type: "uint64" },
|
|
2713
|
-
{ name: "recipient", type: "address" },
|
|
2714
|
-
{ name: "revokerData", type: "uint256" },
|
|
2715
|
-
{ name: "revokerContract", type: "address" },
|
|
2716
|
-
{ name: "scope", type: "uint8" },
|
|
2717
|
-
{ name: "contracts", type: "address[]" },
|
|
2718
|
-
{ name: "handles", type: "bytes32[]" },
|
|
2719
|
-
{ name: "sealingKey", type: "bytes32" },
|
|
2720
|
-
{ name: "issuerSignature", type: "bytes" },
|
|
2721
|
-
{ name: "recipientSignature", type: "bytes" }
|
|
2722
|
-
]
|
|
2723
|
-
}
|
|
2724
|
-
];
|
|
2725
|
-
var ZERO_BYTES32 = `0x${"0".repeat(64)}`;
|
|
2726
|
-
var toChainShare = (acp) => {
|
|
2727
|
-
const pub = ACPUtils.getPublic(acp, true);
|
|
2728
|
-
return {
|
|
2729
|
-
...pub,
|
|
2730
|
-
expiration: BigInt(pub.expiration),
|
|
2731
|
-
revokerData: BigInt(pub.revokerData),
|
|
2732
|
-
sealingKey: ZERO_BYTES32,
|
|
2733
|
-
recipientSignature: "0x"
|
|
2734
|
-
};
|
|
2735
|
-
};
|
|
2736
|
-
var computeShareId = (acp) => {
|
|
2737
|
-
const p = toChainShare(acp);
|
|
2738
|
-
return viem.keccak256(viem.encodeAbiParameters(ACP_TUPLE, [p]));
|
|
2739
|
-
};
|
|
2740
2862
|
var shareOnChain = async (acp, walletClient, registry) => {
|
|
2741
2863
|
if (acp.type !== "sharing") {
|
|
2742
2864
|
throw new Error(`Cannot share a '${acp.type}' ACP on-chain \u2014 only 'sharing' ACPs are shareable.`);
|
|
@@ -2767,7 +2889,7 @@ var getIncomingShares = async (publicClient, registry, recipient) => {
|
|
|
2767
2889
|
args: [recipient]
|
|
2768
2890
|
});
|
|
2769
2891
|
return raw.map((s) => ({
|
|
2770
|
-
shareId:
|
|
2892
|
+
shareId: shareIdOfChainShare(s),
|
|
2771
2893
|
issuer: s.issuer,
|
|
2772
2894
|
expiration: Number(s.expiration),
|
|
2773
2895
|
recipient: s.recipient,
|
|
@@ -2779,9 +2901,9 @@ var getIncomingShares = async (publicClient, registry, recipient) => {
|
|
|
2779
2901
|
issuerSignature: s.issuerSignature
|
|
2780
2902
|
}));
|
|
2781
2903
|
};
|
|
2782
|
-
var importFromChain = async (share, publicClient, walletClient) => {
|
|
2904
|
+
var importFromChain = async (share, publicClient, walletClient, importOptions = {}) => {
|
|
2783
2905
|
const { shareId: _shareId, ...options } = share;
|
|
2784
|
-
return importShared({ ...options, type: "sharing" }, publicClient, walletClient);
|
|
2906
|
+
return importShared({ ...options, type: "sharing" }, publicClient, walletClient, importOptions);
|
|
2785
2907
|
};
|
|
2786
2908
|
var removeShareOnChain = async (shareId, walletClient, registry) => {
|
|
2787
2909
|
if (walletClient.account == null)
|
|
@@ -2819,6 +2941,7 @@ var acps = {
|
|
|
2819
2941
|
revokeACP,
|
|
2820
2942
|
revokeAllACPs,
|
|
2821
2943
|
isACPRevoked,
|
|
2944
|
+
checkAccess,
|
|
2822
2945
|
shareOnChain,
|
|
2823
2946
|
getIncomingShares,
|
|
2824
2947
|
importFromChain,
|
|
@@ -4531,7 +4654,7 @@ var buildDecryptResultHash = (ctHash, cleartext, chainId) => {
|
|
|
4531
4654
|
async function verifyDecryptResult(handle, cleartext, signature, publicClient) {
|
|
4532
4655
|
const chainId = publicClient.chain?.id ?? await publicClient.getChainId();
|
|
4533
4656
|
const expectedSigner = await publicClient.readContract({
|
|
4534
|
-
address:
|
|
4657
|
+
address: await getTaskManagerAddress(publicClient, chainId),
|
|
4535
4658
|
abi: decryptResultSignerAbi,
|
|
4536
4659
|
functionName: "decryptResultSigner",
|
|
4537
4660
|
args: []
|
|
@@ -4651,6 +4774,7 @@ function createCofheClientBase(opts) {
|
|
|
4651
4774
|
zkBuilderAndCrsGenerator: opts.zkBuilderAndCrsGenerator,
|
|
4652
4775
|
initTfhe: opts.initTfhe,
|
|
4653
4776
|
zkProveWorkerFn: opts.zkProveWorkerFn,
|
|
4777
|
+
beforeMainThreadProve: opts.beforeMainThreadProve,
|
|
4654
4778
|
keysStorage,
|
|
4655
4779
|
requireConnected: _requireConnected
|
|
4656
4780
|
});
|
|
@@ -4727,10 +4851,11 @@ function createCofheClientBase(opts) {
|
|
|
4727
4851
|
walletClient
|
|
4728
4852
|
);
|
|
4729
4853
|
},
|
|
4730
|
-
importShared: async (options,
|
|
4854
|
+
importShared: async (options, importOptions = {}) => {
|
|
4731
4855
|
_requireConnected();
|
|
4732
|
-
const {
|
|
4733
|
-
|
|
4856
|
+
const { activate, ...clients } = importOptions;
|
|
4857
|
+
const { publicClient, walletClient } = clients.publicClient ? clients : connectStore.getState();
|
|
4858
|
+
return acps.importShared(options, publicClient, walletClient, { activate });
|
|
4734
4859
|
},
|
|
4735
4860
|
// Get or create methods (require connection)
|
|
4736
4861
|
getOrCreateSelfACP: async (chainId, account, options) => {
|
|
@@ -4773,6 +4898,11 @@ function createCofheClientBase(opts) {
|
|
|
4773
4898
|
const { publicClient } = connectStore.getState();
|
|
4774
4899
|
return acps.isACPRevoked(acp, publicClient);
|
|
4775
4900
|
},
|
|
4901
|
+
checkAccess: async (acp, handle) => {
|
|
4902
|
+
_requireConnected();
|
|
4903
|
+
const { publicClient } = connectStore.getState();
|
|
4904
|
+
return acps.checkAccess(acp, publicClient, handle);
|
|
4905
|
+
},
|
|
4776
4906
|
// On-chain sharing (require connection + config.acp.sharingRegistry)
|
|
4777
4907
|
shareOnChain: async (acp) => {
|
|
4778
4908
|
_requireConnected();
|
|
@@ -4789,10 +4919,10 @@ function createCofheClientBase(opts) {
|
|
|
4789
4919
|
const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
|
|
4790
4920
|
return acps.getIncomingShares(publicClient, sharingRegistry, account);
|
|
4791
4921
|
},
|
|
4792
|
-
importFromChain: async (share) => {
|
|
4922
|
+
importFromChain: async (share, options) => {
|
|
4793
4923
|
_requireConnected();
|
|
4794
4924
|
const { publicClient, walletClient } = connectStore.getState();
|
|
4795
|
-
return acps.importFromChain(share, publicClient, walletClient);
|
|
4925
|
+
return acps.importFromChain(share, publicClient, walletClient, options);
|
|
4796
4926
|
},
|
|
4797
4927
|
dismissShare: async (shareId) => {
|
|
4798
4928
|
_requireConnected();
|
|
@@ -5004,7 +5134,7 @@ var ZkProveWorkerManager = class {
|
|
|
5004
5134
|
/**
|
|
5005
5135
|
* Submit a proof generation request to the worker
|
|
5006
5136
|
*/
|
|
5007
|
-
async submitProof(fheKeyHex, crsHex, items, metadata) {
|
|
5137
|
+
async submitProof(fheKeyHex, crsHex, items, metadata, tfheThreads) {
|
|
5008
5138
|
await this.initializeWorker();
|
|
5009
5139
|
const id = `zkprove-${Date.now()}-${this.requestCounter++}`;
|
|
5010
5140
|
return new Promise((resolve, reject) => {
|
|
@@ -5019,7 +5149,8 @@ var ZkProveWorkerManager = class {
|
|
|
5019
5149
|
fheKeyHex,
|
|
5020
5150
|
crsHex,
|
|
5021
5151
|
items,
|
|
5022
|
-
metadata: Array.from(metadata)
|
|
5152
|
+
metadata: Array.from(metadata),
|
|
5153
|
+
tfheThreads
|
|
5023
5154
|
};
|
|
5024
5155
|
this.worker.postMessage(message);
|
|
5025
5156
|
});
|
|
@@ -5064,17 +5195,91 @@ function areWorkersAvailable() {
|
|
|
5064
5195
|
return typeof Worker !== "undefined";
|
|
5065
5196
|
}
|
|
5066
5197
|
|
|
5198
|
+
// web/tfheThreadPool.ts
|
|
5199
|
+
var MAX_AUTO_THREADS = 8;
|
|
5200
|
+
function resolveThreadCount(setting = "auto") {
|
|
5201
|
+
if (setting === false)
|
|
5202
|
+
return 1;
|
|
5203
|
+
if (typeof setting === "number") {
|
|
5204
|
+
return Number.isFinite(setting) && setting >= 1 ? Math.floor(setting) : 1;
|
|
5205
|
+
}
|
|
5206
|
+
const cores = globalThis.navigator?.hardwareConcurrency ?? 1;
|
|
5207
|
+
if (!Number.isFinite(cores) || cores < 1)
|
|
5208
|
+
return 1;
|
|
5209
|
+
return Math.min(Math.floor(cores), MAX_AUTO_THREADS);
|
|
5210
|
+
}
|
|
5211
|
+
function isCrossOriginIsolated() {
|
|
5212
|
+
return globalThis.crossOriginIsolated === true;
|
|
5213
|
+
}
|
|
5214
|
+
async function initTfheThreadPool(mod, setting = "auto") {
|
|
5215
|
+
if (setting === false) {
|
|
5216
|
+
return { enabled: false, threads: 1, reason: "disabled via config.tfheThreads" };
|
|
5217
|
+
}
|
|
5218
|
+
if (typeof mod.initThreadPool !== "function") {
|
|
5219
|
+
return { enabled: false, threads: 1, reason: "tfhe build has no initThreadPool (single-threaded wasm)" };
|
|
5220
|
+
}
|
|
5221
|
+
if (typeof Worker === "undefined") {
|
|
5222
|
+
return { enabled: false, threads: 1, reason: "Worker is unavailable" };
|
|
5223
|
+
}
|
|
5224
|
+
if (!isCrossOriginIsolated()) {
|
|
5225
|
+
return {
|
|
5226
|
+
enabled: false,
|
|
5227
|
+
threads: 1,
|
|
5228
|
+
reason: "not cross-origin isolated \u2014 serve the page with Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp (or credentialless) to enable multi-threaded proving"
|
|
5229
|
+
};
|
|
5230
|
+
}
|
|
5231
|
+
const threads = resolveThreadCount(setting);
|
|
5232
|
+
if (threads <= 1) {
|
|
5233
|
+
return { enabled: false, threads: 1, reason: "resolved to a single thread" };
|
|
5234
|
+
}
|
|
5235
|
+
try {
|
|
5236
|
+
await mod.initThreadPool(threads);
|
|
5237
|
+
return { enabled: true, threads };
|
|
5238
|
+
} catch (error) {
|
|
5239
|
+
return {
|
|
5240
|
+
enabled: false,
|
|
5241
|
+
threads: 1,
|
|
5242
|
+
reason: `initThreadPool failed: ${error instanceof Error ? error.message : String(error)}`
|
|
5243
|
+
};
|
|
5244
|
+
}
|
|
5245
|
+
}
|
|
5246
|
+
|
|
5067
5247
|
// web/index.ts
|
|
5068
5248
|
var tfheModule = null;
|
|
5069
5249
|
var tfheInitialized = false;
|
|
5070
|
-
|
|
5250
|
+
var tfheInitPromise = null;
|
|
5251
|
+
var threadPoolPromise = null;
|
|
5252
|
+
var threadPoolResult = null;
|
|
5253
|
+
function getTfheThreadPoolStatus() {
|
|
5254
|
+
return threadPoolResult;
|
|
5255
|
+
}
|
|
5256
|
+
var initTfhe = async () => {
|
|
5071
5257
|
if (tfheInitialized)
|
|
5072
5258
|
return false;
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5259
|
+
if (tfheInitPromise) {
|
|
5260
|
+
await tfheInitPromise;
|
|
5261
|
+
return false;
|
|
5262
|
+
}
|
|
5263
|
+
tfheInitPromise = (async () => {
|
|
5264
|
+
const mod = await import('tfhe');
|
|
5265
|
+
await mod.default();
|
|
5266
|
+
await mod.init_panic_hook();
|
|
5267
|
+
tfheModule = mod;
|
|
5268
|
+
tfheInitialized = true;
|
|
5269
|
+
})();
|
|
5270
|
+
try {
|
|
5271
|
+
await tfheInitPromise;
|
|
5272
|
+
} catch (error) {
|
|
5273
|
+
tfheInitPromise = null;
|
|
5274
|
+
throw error;
|
|
5275
|
+
}
|
|
5077
5276
|
return true;
|
|
5277
|
+
};
|
|
5278
|
+
function createStartMainThreadPool(tfheThreads) {
|
|
5279
|
+
return async () => {
|
|
5280
|
+
threadPoolPromise ??= initTfheThreadPool(requireTfhe(), tfheThreads);
|
|
5281
|
+
threadPoolResult = await threadPoolPromise;
|
|
5282
|
+
};
|
|
5078
5283
|
}
|
|
5079
5284
|
function requireTfhe() {
|
|
5080
5285
|
if (!tfheModule) {
|
|
@@ -5110,13 +5315,15 @@ var zkBuilderAndCrsGenerator = (fhe, crs) => {
|
|
|
5110
5315
|
const zkCrs = _deserializeCompactPkeCrs(crs);
|
|
5111
5316
|
return { zkBuilder, zkCrs };
|
|
5112
5317
|
};
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5318
|
+
function createZkProveWithWorker(tfheThreads) {
|
|
5319
|
+
return async function zkProveWithWorker2(fheKeyHex, crsHex, items, metadata) {
|
|
5320
|
+
const serializedItems = items.map((item) => ({
|
|
5321
|
+
utype: fheTypeToString(item.utype),
|
|
5322
|
+
data: typeof item.data === "bigint" ? item.data.toString() : item.data
|
|
5323
|
+
}));
|
|
5324
|
+
const workerManager2 = getWorkerManager();
|
|
5325
|
+
return await workerManager2.submitProof(fheKeyHex, crsHex, serializedItems, metadata, tfheThreads);
|
|
5326
|
+
};
|
|
5120
5327
|
}
|
|
5121
5328
|
function createCofheConfig(config) {
|
|
5122
5329
|
return createCofheConfigBase({
|
|
@@ -5132,9 +5339,10 @@ function createCofheClient(config) {
|
|
|
5132
5339
|
tfhePublicKeyDeserializer,
|
|
5133
5340
|
compactPkeCrsDeserializer,
|
|
5134
5341
|
initTfhe,
|
|
5342
|
+
beforeMainThreadProve: createStartMainThreadPool(config.tfheThreads),
|
|
5135
5343
|
// Always provide the worker function if available - config.useWorkers controls usage
|
|
5136
5344
|
// areWorkersAvailable will return true if the Worker API is available and false in Node.js
|
|
5137
|
-
zkProveWorkerFn: areWorkersAvailable() ?
|
|
5345
|
+
zkProveWorkerFn: areWorkersAvailable() ? createZkProveWithWorker(config.tfheThreads) : void 0
|
|
5138
5346
|
});
|
|
5139
5347
|
}
|
|
5140
5348
|
function createCofheClientWithCustomWorker(config, customZkProveWorkerFn) {
|
|
@@ -5144,6 +5352,7 @@ function createCofheClientWithCustomWorker(config, customZkProveWorkerFn) {
|
|
|
5144
5352
|
tfhePublicKeyDeserializer,
|
|
5145
5353
|
compactPkeCrsDeserializer,
|
|
5146
5354
|
initTfhe,
|
|
5355
|
+
beforeMainThreadProve: createStartMainThreadPool(config.tfheThreads),
|
|
5147
5356
|
zkProveWorkerFn: customZkProveWorkerFn
|
|
5148
5357
|
});
|
|
5149
5358
|
}
|
|
@@ -5153,5 +5362,6 @@ exports.createCofheClient = createCofheClient;
|
|
|
5153
5362
|
exports.createCofheClientWithCustomWorker = createCofheClientWithCustomWorker;
|
|
5154
5363
|
exports.createCofheConfig = createCofheConfig;
|
|
5155
5364
|
exports.createSsrStorage = createSsrStorage;
|
|
5365
|
+
exports.getTfheThreadPoolStatus = getTfheThreadPoolStatus;
|
|
5156
5366
|
exports.hasDOM = hasDOM;
|
|
5157
5367
|
exports.terminateWorker = terminateWorker;
|