@cofhe/sdk 0.7.1 → 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.
Files changed (79) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/acps/acp.ts +10 -1
  3. package/acps/index.ts +11 -0
  4. package/acps/onchain-utils.ts +188 -49
  5. package/acps/registry.ts +73 -0
  6. package/acps/test/onchainAccessStatus.test.ts +116 -0
  7. package/acps/types.ts +16 -0
  8. package/chains/chains/arbitrum.ts +14 -0
  9. package/chains/chains/ethereum.ts +14 -0
  10. package/chains/index.ts +5 -1
  11. package/chains/test/chains.test.ts +24 -3
  12. package/core/acps.ts +51 -143
  13. package/core/client.ts +13 -8
  14. package/core/clientTypes.ts +29 -4
  15. package/core/config.ts +25 -1
  16. package/core/consts.ts +14 -2
  17. package/core/decrypt/verifyDecryptResult.ts +4 -3
  18. package/core/encrypt/encryptInputsBuilder.ts +6 -0
  19. package/core/encrypt/zkPackProveVerify.ts +7 -1
  20. package/core/error.ts +1 -0
  21. package/core/fetchKeys.ts +2 -2
  22. package/core/index.ts +9 -1
  23. package/core/keyStore.ts +23 -10
  24. package/core/taskManager.ts +48 -0
  25. package/core/test/acps.test.ts +91 -1
  26. package/core/test/client.test.ts +41 -0
  27. package/core/test/config.test.ts +16 -0
  28. package/core/test/decrypt.test.ts +11 -4
  29. package/core/test/encryptInputsBuilder.test.ts +1 -1
  30. package/core/test/fetchKeys.test.ts +23 -2
  31. package/core/test/keyStore.test.ts +18 -6
  32. package/core/test/taskManager.test.ts +57 -0
  33. package/core/types.ts +8 -0
  34. package/dist/acps.cjs +314 -35
  35. package/dist/acps.d.cts +251 -4
  36. package/dist/acps.d.ts +251 -4
  37. package/dist/acps.js +2 -2
  38. package/dist/chains.cjs +26 -0
  39. package/dist/chains.d.cts +45 -1
  40. package/dist/chains.d.ts +45 -1
  41. package/dist/chains.js +1 -1
  42. package/dist/{chunk-43USWPEH.js → chunk-GGI7Y6AW.js} +59 -264
  43. package/dist/chunk-KSOV5B4B.js +50 -0
  44. package/dist/{chunk-ESMZCFJY.js → chunk-NMKMCAI3.js} +4 -2
  45. package/dist/{chunk-Q7CBWGQX.js → chunk-UJYOBHYA.js} +374 -37
  46. package/dist/{chunk-N6IDQRRU.js → chunk-UKQAJK4N.js} +25 -1
  47. package/dist/{clientTypes-BN3nbzYM.d.ts → clientTypes-5YPPR16m.d.ts} +77 -14
  48. package/dist/{clientTypes-CYZjFznO.d.cts → clientTypes-D3aIXmUp.d.cts} +77 -14
  49. package/dist/core.cjs +271 -136
  50. package/dist/core.d.cts +29 -8
  51. package/dist/core.d.ts +29 -8
  52. package/dist/core.js +4 -4
  53. package/dist/node.cjs +266 -136
  54. package/dist/node.d.cts +2 -2
  55. package/dist/node.d.ts +2 -2
  56. package/dist/node.js +5 -5
  57. package/dist/{acp-Wi6isVQI.d.cts → onchain-utils-CUAK8glx.d.cts} +31 -1
  58. package/dist/{acp-Wi6isVQI.d.ts → onchain-utils-CUAK8glx.d.ts} +31 -1
  59. package/dist/web.cjs +360 -150
  60. package/dist/web.d.cts +49 -3
  61. package/dist/web.d.ts +49 -3
  62. package/dist/web.js +51 -20
  63. package/dist/zkProve.worker.cjs +69 -15
  64. package/dist/zkProve.worker.js +23 -17
  65. package/node/storage.ts +2 -2
  66. package/node/test/inherited.test.ts +5 -1
  67. package/node/test/storage-memory-fallback.test.ts +47 -0
  68. package/package.json +5 -3
  69. package/web/index.ts +100 -26
  70. package/web/test/countingZkProveWorker.ts +31 -0
  71. package/web/test/inherited.web.test.ts +5 -1
  72. package/web/test/mainThreadPool.web.test.ts +174 -0
  73. package/web/test/threadPoolBenchHelper.ts +140 -0
  74. package/web/test/threadPoolOff.web.test.ts +17 -0
  75. package/web/test/threadPoolOn.web.test.ts +80 -0
  76. package/web/test/workerInitRace.web.test.ts +79 -0
  77. package/web/tfheThreadPool.ts +140 -0
  78. package/web/workerManager.ts +4 -2
  79. package/web/zkProve.worker.ts +42 -17
package/dist/node.cjs CHANGED
@@ -113,7 +113,8 @@ var bigintSafeJsonStringify = (value) => {
113
113
  var isCofheError = (error) => error instanceof CofheError;
114
114
 
115
115
  // core/consts.ts
116
- var TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
116
+ var COFHE_ADDRESS_BOOK_ADDRESS = "0xC0F4e00E531a2B086492Ae3DCC1515038307196b";
117
+ var TASK_MANAGER_ID = 1n;
117
118
  var MOCKS_ZK_VERIFIER_ADDRESS = "0x0000000000000000000000000000000000005001";
118
119
  var MOCKS_THRESHOLD_NETWORK_ADDRESS = "0x0000000000000000000000000000000000005002";
119
120
  var MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = "0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512";
@@ -713,6 +714,8 @@ var CofheConfigSchema = zod.z.object({
713
714
  }).or(zod.z.null()).default(null),
714
715
  /** Whether to use Web Workers for ZK proof generation (web platform only) */
715
716
  useWorkers: zod.z.boolean().optional().default(true),
717
+ /** How many threads tfhe's rayon pool may use for ZK proof generation (web platform only) */
718
+ tfheThreads: zod.z.union([zod.z.number().int().positive(), zod.z.literal("auto"), zod.z.literal(false)]).optional().default("auto"),
716
719
  /** ACP acp defaults */
717
720
  acp: zod.z.object({
718
721
  defaultRevoker: zod.z.custom().optional(),
@@ -818,6 +821,9 @@ var DEFAULT_KEYS_STORE = {
818
821
  fhe: {},
819
822
  crs: {}
820
823
  };
824
+ function isSecurityZoneRecord(value) {
825
+ return value != null && typeof value === "object";
826
+ }
821
827
  function isStoreWithPersist(store) {
822
828
  return "persist" in store;
823
829
  }
@@ -832,10 +838,10 @@ function createKeysStore(storage) {
832
838
  const stored = keysStore.getState().fhe[chainId]?.[securityZone];
833
839
  return stored;
834
840
  };
835
- const getCrs = (chainId) => {
836
- if (chainId == null)
841
+ const getCrs = (chainId, securityZone = 0) => {
842
+ if (chainId == null || securityZone == null)
837
843
  return void 0;
838
- const stored = keysStore.getState().crs[chainId];
844
+ const stored = keysStore.getState().crs[chainId]?.[securityZone];
839
845
  return stored;
840
846
  };
841
847
  const setFheKey = (chainId, securityZone, key) => {
@@ -847,10 +853,12 @@ function createKeysStore(storage) {
847
853
  })
848
854
  );
849
855
  };
850
- const setCrs = (chainId, crs) => {
856
+ const setCrs = (chainId, securityZone, crs) => {
851
857
  keysStore.setState(
852
858
  immer.produce((state) => {
853
- state.crs[chainId] = crs;
859
+ if (state.crs[chainId] == null)
860
+ state.crs[chainId] = {};
861
+ state.crs[chainId][securityZone] = crs;
854
862
  })
855
863
  );
856
864
  };
@@ -898,7 +906,13 @@ function createStoreWithPersit(storage) {
898
906
  const currentZones = current.fhe[chainId] || {};
899
907
  mergedFhe[chainId] = { ...persistedZones, ...currentZones };
900
908
  }
901
- const mergedCrs = { ...persisted.crs, ...current.crs };
909
+ const mergedCrs = {};
910
+ const allCrsChainIds = /* @__PURE__ */ new Set([...Object.keys(current.crs), ...Object.keys(persisted.crs)]);
911
+ for (const chainId of allCrsChainIds) {
912
+ const persistedZones = isSecurityZoneRecord(persisted.crs[chainId]) ? persisted.crs[chainId] : {};
913
+ const currentZones = isSecurityZoneRecord(current.crs[chainId]) ? current.crs[chainId] : {};
914
+ mergedCrs[chainId] = { ...persistedZones, ...currentZones };
915
+ }
902
916
  return {
903
917
  fhe: mergedFhe,
904
918
  crs: mergedCrs
@@ -960,7 +974,7 @@ var fetchFhePublicKey = async (coFheUrl, chainId, securityZone, tfhePublicKeyDes
960
974
  return [pk_data, true];
961
975
  };
962
976
  var fetchCrs = async (coFheUrl, chainId, securityZone, compactPkeCrsDeserializer2, keysStorage) => {
963
- const storedKey = keysStorage?.getCrs(chainId);
977
+ const storedKey = keysStorage?.getCrs(chainId, securityZone);
964
978
  const [storedKeyValid] = checkKeyValidity(storedKey, compactPkeCrsDeserializer2);
965
979
  if (storedKeyValid)
966
980
  return [storedKey, false];
@@ -987,7 +1001,7 @@ var fetchCrs = async (coFheUrl, chainId, securityZone, compactPkeCrsDeserializer
987
1001
  console.error(`Error serializing CRS ${err}`);
988
1002
  throw new Error(`Error serializing CRS; ${err}`);
989
1003
  }
990
- keysStorage?.setCrs(chainId, crs_data);
1004
+ keysStorage?.setCrs(chainId, securityZone, crs_data);
991
1005
  return [crs_data, true];
992
1006
  };
993
1007
  var fetchKeys = async (config, chainId, securityZone = 0, tfhePublicKeyDeserializer2, compactPkeCrsDeserializer2, keysStorage) => {
@@ -1099,6 +1113,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1099
1113
  zkBuilderAndCrsGenerator;
1100
1114
  initTfhe;
1101
1115
  zkProveWorkerFn;
1116
+ beforeMainThreadProve;
1102
1117
  keysStorage;
1103
1118
  // Worker configuration (from config, overrideable)
1104
1119
  useWorker;
@@ -1156,6 +1171,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1156
1171
  this.zkBuilderAndCrsGenerator = params.zkBuilderAndCrsGenerator;
1157
1172
  this.initTfhe = params.initTfhe;
1158
1173
  this.zkProveWorkerFn = params.zkProveWorkerFn;
1174
+ this.beforeMainThreadProve = params.beforeMainThreadProve;
1159
1175
  this.keysStorage = params.keysStorage;
1160
1176
  this.useWorker = params.config?.useWorkers ?? true;
1161
1177
  }
@@ -1446,6 +1462,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1446
1462
  }
1447
1463
  }
1448
1464
  if (proof == null) {
1465
+ await this.beforeMainThreadProve?.();
1449
1466
  proof = await zkProve(zkBuilder, zkCrs, metadata);
1450
1467
  usedWorker = false;
1451
1468
  }
@@ -1842,11 +1859,40 @@ var SignatureUtils = {
1842
1859
  throw new Error(`Unknown acp type: ${acpType}`);
1843
1860
  }
1844
1861
  };
1862
+ var ADDRESS_BOOK_ABI = viem.parseAbi([
1863
+ "function getTm(uint256 id) view returns (address)",
1864
+ "error TaskManagerNotSet(uint256 id)"
1865
+ ]);
1866
+ var taskManagerAddressCache = /* @__PURE__ */ new Map();
1867
+ var getTaskManagerAddress = async (publicClient, chainId) => {
1868
+ const id = chainId ?? publicClient.chain?.id ?? await publicClient.getChainId();
1869
+ const cached = taskManagerAddressCache.get(id);
1870
+ if (cached != null)
1871
+ return cached;
1872
+ const pending = publicClient.readContract({
1873
+ address: COFHE_ADDRESS_BOOK_ADDRESS,
1874
+ abi: ADDRESS_BOOK_ABI,
1875
+ functionName: "getTm",
1876
+ args: [TASK_MANAGER_ID]
1877
+ }).catch((error) => {
1878
+ taskManagerAddressCache.delete(id);
1879
+ throw CofheError.fromError(error, {
1880
+ code: "TASK_MANAGER_UNRESOLVED" /* TaskManagerUnresolved */,
1881
+ message: `Failed to resolve the Task Manager from the CoFHEAddressBook on chain ${id}`,
1882
+ hint: "Ensure CoFHE is deployed on this chain. On a local hardhat / anvil chain, deploy the CoFHE mocks first.",
1883
+ context: { chainId: id, addressBook: COFHE_ADDRESS_BOOK_ADDRESS, taskManagerId: TASK_MANAGER_ID }
1884
+ });
1885
+ });
1886
+ taskManagerAddressCache.set(id, pending);
1887
+ return pending;
1888
+ };
1889
+
1890
+ // acps/onchain-utils.ts
1845
1891
  var getAclAddress = async (publicClient) => {
1846
1892
  const ACL_IFACE = "function acl() view returns (address)";
1847
1893
  const aclAbi = viem.parseAbi([ACL_IFACE]);
1848
1894
  return await publicClient.readContract({
1849
- address: TASK_MANAGER_ADDRESS,
1895
+ address: await getTaskManagerAddress(publicClient),
1850
1896
  abi: aclAbi,
1851
1897
  functionName: "acl"
1852
1898
  });
@@ -1873,6 +1919,34 @@ var getAclEIP712Domain = async (publicClient) => {
1873
1919
  verifyingContract
1874
1920
  };
1875
1921
  };
1922
+ var toACPTuple = (acp) => ({
1923
+ issuer: acp.issuer,
1924
+ expiration: BigInt(acp.expiration),
1925
+ recipient: acp.recipient,
1926
+ revokerData: BigInt(acp.revokerData),
1927
+ revokerContract: acp.revokerContract,
1928
+ scope: acp.scope,
1929
+ contracts: acp.contracts,
1930
+ handles: acp.handles,
1931
+ sealingKey: acp.sealingKey,
1932
+ issuerSignature: acp.issuerSignature,
1933
+ recipientSignature: acp.recipientSignature
1934
+ });
1935
+ function revertErrorName(err, abi) {
1936
+ const walk = err?.walk;
1937
+ if (typeof walk === "function") {
1938
+ const revertError = walk.call(err, (e) => e?.name === "ContractFunctionRevertedError");
1939
+ if (revertError)
1940
+ return revertError.data?.errorName ?? "";
1941
+ }
1942
+ const customErrorName = extractCustomErrorFromDetails(err, abi);
1943
+ if (customErrorName)
1944
+ return customErrorName;
1945
+ const hhDetailsData = extractReturnData(err);
1946
+ if (hhDetailsData != null)
1947
+ return viem.decodeErrorResult({ abi, data: hhDetailsData }).errorName;
1948
+ return void 0;
1949
+ }
1876
1950
  var checkACPValidityOnChain = async (acp, publicClient) => {
1877
1951
  const aclAddress = await getAclAddress(publicClient);
1878
1952
  try {
@@ -1880,43 +1954,54 @@ var checkACPValidityOnChain = async (acp, publicClient) => {
1880
1954
  address: aclAddress,
1881
1955
  abi: checkACPValidityAbi,
1882
1956
  functionName: "checkPermissionValidity",
1883
- args: [
1884
- {
1885
- issuer: acp.issuer,
1886
- expiration: BigInt(acp.expiration),
1887
- recipient: acp.recipient,
1888
- revokerData: BigInt(acp.revokerData),
1889
- revokerContract: acp.revokerContract,
1890
- scope: acp.scope,
1891
- contracts: acp.contracts,
1892
- handles: acp.handles,
1893
- sealingKey: acp.sealingKey,
1894
- issuerSignature: acp.issuerSignature,
1895
- recipientSignature: acp.recipientSignature
1896
- }
1897
- ]
1957
+ args: [toACPTuple(acp)]
1898
1958
  });
1899
1959
  return true;
1900
1960
  } catch (err) {
1901
- if (err instanceof viem.BaseError) {
1902
- const revertError = err.walk((err2) => err2 instanceof viem.ContractFunctionRevertedError);
1903
- if (revertError instanceof viem.ContractFunctionRevertedError) {
1904
- const errorName = revertError.data?.errorName ?? "";
1905
- throw new Error(errorName);
1906
- }
1907
- }
1908
- const customErrorName = extractCustomErrorFromDetails(err, checkACPValidityAbi);
1909
- if (customErrorName) {
1910
- throw new Error(customErrorName);
1911
- }
1912
- const hhDetailsData = extractReturnData(err);
1913
- if (hhDetailsData != null) {
1914
- const decoded = viem.decodeErrorResult({
1915
- abi: checkACPValidityAbi,
1916
- data: hhDetailsData
1961
+ const errorName = revertErrorName(err, checkACPValidityAbi);
1962
+ if (errorName !== void 0)
1963
+ throw new Error(errorName);
1964
+ throw err;
1965
+ }
1966
+ };
1967
+ var PERMISSION_ERROR_STATUS = {
1968
+ PermissionInvalid_Expired: "expired",
1969
+ PermissionInvalid_Disabled: "revoked",
1970
+ PermissionInvalid_IssuerSignature: "invalid-issuer-signature",
1971
+ PermissionInvalid_RecipientSignature: "invalid-recipient-signature"
1972
+ };
1973
+ var getACPAccessStatusOnChain = async (acp, publicClient, handle) => {
1974
+ const aclAddress = await getAclAddress(publicClient);
1975
+ try {
1976
+ if (handle === void 0) {
1977
+ await publicClient.simulateContract({
1978
+ address: aclAddress,
1979
+ abi: acpAccessAbi,
1980
+ functionName: "checkPermissionValidity",
1981
+ args: [toACPTuple(acp)]
1917
1982
  });
1918
- throw new Error(decoded.errorName);
1983
+ return "valid";
1919
1984
  }
1985
+ const ctHash = BigInt(handle);
1986
+ const allowed = await publicClient.readContract({
1987
+ address: aclAddress,
1988
+ abi: acpAccessAbi,
1989
+ functionName: "isAllowedWithPermission",
1990
+ args: [toACPTuple(acp), ctHash]
1991
+ });
1992
+ if (allowed)
1993
+ return "allowed";
1994
+ const issuerAllowed = await publicClient.readContract({
1995
+ address: aclAddress,
1996
+ abi: acpAccessAbi,
1997
+ functionName: "isAllowed",
1998
+ args: [ctHash, acp.issuer]
1999
+ });
2000
+ return issuerAllowed ? "out-of-scope" : "issuer-not-allowed";
2001
+ } catch (err) {
2002
+ const status = PERMISSION_ERROR_STATUS[revertErrorName(err, acpAccessAbi) ?? ""];
2003
+ if (status)
2004
+ return status;
1920
2005
  throw err;
1921
2006
  }
1922
2007
  };
@@ -1938,7 +2023,8 @@ function extractCustomErrorFromDetails(err, abi) {
1938
2023
  function extractReturnData(err) {
1939
2024
  const anyErr = err;
1940
2025
  const s = anyErr?.details ?? anyErr?.cause?.details ?? anyErr?.shortMessage ?? anyErr?.message ?? String(err);
1941
- return s.match(/return data:\s*(0x[a-fA-F0-9]+)/)?.[1];
2026
+ const match = s.match(/return data:\s*(0x[a-fA-F0-9]+)/) ?? s.match(/custom error (0x[a-fA-F0-9]{8,})/);
2027
+ return match?.[1];
1942
2028
  }
1943
2029
  var checkACPValidityAbi = [
1944
2030
  {
@@ -2038,6 +2124,58 @@ var checkACPValidityAbi = [
2038
2124
  inputs: []
2039
2125
  }
2040
2126
  ];
2127
+ var acpAccessAbi = [
2128
+ ...checkACPValidityAbi,
2129
+ {
2130
+ type: "function",
2131
+ name: "isAllowedWithPermission",
2132
+ inputs: [checkACPValidityAbi[0].inputs[0], { name: "handle", type: "uint256", internalType: "uint256" }],
2133
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
2134
+ stateMutability: "view"
2135
+ },
2136
+ {
2137
+ type: "function",
2138
+ name: "isAllowed",
2139
+ inputs: [
2140
+ { name: "handle", type: "uint256", internalType: "uint256" },
2141
+ { name: "account", type: "address", internalType: "address" }
2142
+ ],
2143
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
2144
+ stateMutability: "view"
2145
+ }
2146
+ ];
2147
+ var ACL_SERVED_ADDRESSES_ABI = viem.parseAbi([
2148
+ "function acl() view returns (address)",
2149
+ "function defaultRevokerContract() view returns (address)",
2150
+ "function shareRegistry() view returns (address)"
2151
+ ]);
2152
+ var aclServedAddressesCache = /* @__PURE__ */ new Map();
2153
+ var clearAclServedAddresses = () => aclServedAddressesCache.clear();
2154
+ var getAclServedAddresses = async (publicClient, chainId) => {
2155
+ const cached = aclServedAddressesCache.get(chainId);
2156
+ if (cached != null)
2157
+ return cached;
2158
+ let aclAddress;
2159
+ try {
2160
+ aclAddress = await publicClient.readContract({
2161
+ address: await getTaskManagerAddress(publicClient, chainId),
2162
+ abi: ACL_SERVED_ADDRESSES_ABI,
2163
+ functionName: "acl"
2164
+ });
2165
+ } catch {
2166
+ return {};
2167
+ }
2168
+ const [defaultRevoker, shareRegistry] = await Promise.all([
2169
+ publicClient.readContract({ address: aclAddress, abi: ACL_SERVED_ADDRESSES_ABI, functionName: "defaultRevokerContract" }).catch(() => void 0),
2170
+ publicClient.readContract({ address: aclAddress, abi: ACL_SERVED_ADDRESSES_ABI, functionName: "shareRegistry" }).catch(() => void 0)
2171
+ ]);
2172
+ const resolved = {
2173
+ defaultRevoker: defaultRevoker != null && defaultRevoker !== viem.zeroAddress ? defaultRevoker : void 0,
2174
+ shareRegistry: shareRegistry != null && shareRegistry !== viem.zeroAddress ? shareRegistry : void 0
2175
+ };
2176
+ aclServedAddressesCache.set(chainId, resolved);
2177
+ return resolved;
2178
+ };
2041
2179
 
2042
2180
  // acps/acp.ts
2043
2181
  var ACPUtils = {
@@ -2351,8 +2489,62 @@ var ACPUtils = {
2351
2489
  checkValidityOnChain: async (acp, publicClient) => {
2352
2490
  const publicAcp = ACPUtils.getPublic(acp);
2353
2491
  return checkACPValidityOnChain(publicAcp, publicClient);
2492
+ },
2493
+ /**
2494
+ * The acp on-chain status as a value instead of a revert: 'valid' or why not, and given a
2495
+ * handle, whether the acp may read it (see `ACPAccessStatus`).
2496
+ */
2497
+ checkAccessOnChain: async (acp, publicClient, handle) => {
2498
+ return getACPAccessStatusOnChain(ACPUtils.getPublic(acp), publicClient, handle);
2354
2499
  }
2355
2500
  };
2501
+ var ACP_REVOKER_ABI = viem.parseAbi([
2502
+ "function revokeSingle(uint256 id)",
2503
+ "function revokeAllExisting()",
2504
+ "function disabled(address issuer, uint256 id) view returns (bool)"
2505
+ ]);
2506
+ var ACP_SHARE_REGISTRY_ABI = viem.parseAbi([
2507
+ "struct ACP { address issuer; uint64 expiration; address recipient; uint256 revokerData; address revokerContract; uint8 scope; address[] contracts; bytes32[] handles; bytes32 sealingKey; bytes issuerSignature; bytes recipientSignature; }",
2508
+ "function share(ACP calldata acp) external returns (bytes32)",
2509
+ "function removeShare(bytes32 shareId) external",
2510
+ "function sharesFor(address recipient) external view returns (ACP[] memory)",
2511
+ "function getShare(bytes32 shareId) external view returns (ACP memory)",
2512
+ "function isShareValid(bytes32 shareId) external view returns (bool)"
2513
+ ]);
2514
+ var ACP_SHARE_TUPLE_ABI = [
2515
+ {
2516
+ type: "tuple",
2517
+ components: [
2518
+ { name: "issuer", type: "address" },
2519
+ { name: "expiration", type: "uint64" },
2520
+ { name: "recipient", type: "address" },
2521
+ { name: "revokerData", type: "uint256" },
2522
+ { name: "revokerContract", type: "address" },
2523
+ { name: "scope", type: "uint8" },
2524
+ { name: "contracts", type: "address[]" },
2525
+ { name: "handles", type: "bytes32[]" },
2526
+ { name: "sealingKey", type: "bytes32" },
2527
+ { name: "issuerSignature", type: "bytes" },
2528
+ { name: "recipientSignature", type: "bytes" }
2529
+ ]
2530
+ }
2531
+ ];
2532
+ var ZERO_BYTES32 = `0x${"0".repeat(64)}`;
2533
+ var toChainShare = (acp) => {
2534
+ const pub = ACPUtils.getPublic(acp, true);
2535
+ return {
2536
+ ...pub,
2537
+ expiration: BigInt(pub.expiration),
2538
+ revokerData: BigInt(pub.revokerData),
2539
+ sealingKey: ZERO_BYTES32,
2540
+ recipientSignature: "0x"
2541
+ };
2542
+ };
2543
+ var computeShareId = (acp) => {
2544
+ const p = toChainShare(acp);
2545
+ return viem.keccak256(viem.encodeAbiParameters(ACP_SHARE_TUPLE_ABI, [p]));
2546
+ };
2547
+ var shareIdOfChainShare = (share) => viem.keccak256(viem.encodeAbiParameters(ACP_SHARE_TUPLE_ABI, [share]));
2356
2548
  var ACP_STORE_DEFAULTS = {
2357
2549
  acps: {},
2358
2550
  activeACPHash: {}
@@ -2478,11 +2670,6 @@ var acpStore = {
2478
2670
  removeActiveACPHash,
2479
2671
  resetStore
2480
2672
  };
2481
- var ACP_VALIDATOR_ABI = viem.parseAbi([
2482
- "function revokeSingle(uint256 id)",
2483
- "function revokeAllExisting()",
2484
- "function disabled(address issuer, uint256 id) view returns (bool)"
2485
- ]);
2486
2673
  var storeACP = async (acp, publicClient, walletClient) => {
2487
2674
  const chainId = await publicClient.getChainId();
2488
2675
  const account = walletClient.account.address;
@@ -2509,8 +2696,8 @@ var createSelf = async (options, publicClient, walletClient) => {
2509
2696
  var createSharing = async (options, publicClient, walletClient) => {
2510
2697
  return createACPWithSign(options, publicClient, walletClient, ACPUtils.createSharingAndSign, false);
2511
2698
  };
2512
- var importShared = async (options, publicClient, walletClient) => {
2513
- return createACPWithSign(options, publicClient, walletClient, ACPUtils.importSharedAndSign);
2699
+ var importShared = async (options, publicClient, walletClient, { activate = true } = {}) => {
2700
+ return createACPWithSign(options, publicClient, walletClient, ACPUtils.importSharedAndSign, activate);
2514
2701
  };
2515
2702
  var getHash = (acp) => {
2516
2703
  return ACPUtils.getHash(acp);
@@ -2572,38 +2759,6 @@ var applyACPDefaults = (options, acpConfig, chainId) => {
2572
2759
  }
2573
2760
  return result;
2574
2761
  };
2575
- var ACL_SERVED_ADDRESSES_ABI = viem.parseAbi([
2576
- "function acl() view returns (address)",
2577
- "function defaultRevokerContract() view returns (address)",
2578
- "function shareRegistry() view returns (address)"
2579
- ]);
2580
- var aclServedAddressesCache = /* @__PURE__ */ new Map();
2581
- var clearAclServedAddresses = () => aclServedAddressesCache.clear();
2582
- var getAclServedAddresses = async (publicClient, chainId) => {
2583
- const cached = aclServedAddressesCache.get(chainId);
2584
- if (cached != null)
2585
- return cached;
2586
- let aclAddress;
2587
- try {
2588
- aclAddress = await publicClient.readContract({
2589
- address: TASK_MANAGER_ADDRESS,
2590
- abi: ACL_SERVED_ADDRESSES_ABI,
2591
- functionName: "acl"
2592
- });
2593
- } catch {
2594
- return {};
2595
- }
2596
- const [defaultRevoker, shareRegistry] = await Promise.all([
2597
- publicClient.readContract({ address: aclAddress, abi: ACL_SERVED_ADDRESSES_ABI, functionName: "defaultRevokerContract" }).catch(() => void 0),
2598
- publicClient.readContract({ address: aclAddress, abi: ACL_SERVED_ADDRESSES_ABI, functionName: "shareRegistry" }).catch(() => void 0)
2599
- ]);
2600
- const resolved = {
2601
- defaultRevoker: defaultRevoker != null && defaultRevoker !== viem.zeroAddress ? defaultRevoker : void 0,
2602
- shareRegistry: shareRegistry != null && shareRegistry !== viem.zeroAddress ? shareRegistry : void 0
2603
- };
2604
- aclServedAddressesCache.set(chainId, resolved);
2605
- return resolved;
2606
- };
2607
2762
  var applyACPDefaultsFromChain = async (options, acpConfig, publicClient, chainId) => {
2608
2763
  const hasExplicitRevoker = acpConfig?.defaultRevoker?.[chainId] != null || options.revokerData != null || options.revokerContract != null;
2609
2764
  if (hasExplicitRevoker)
@@ -2623,7 +2778,7 @@ var revokeACP = async (acp, walletClient) => {
2623
2778
  }
2624
2779
  return walletClient.writeContract({
2625
2780
  address: acp.revokerContract,
2626
- abi: ACP_VALIDATOR_ABI,
2781
+ abi: ACP_REVOKER_ABI,
2627
2782
  functionName: "revokeSingle",
2628
2783
  args: [BigInt(acp.revokerData)],
2629
2784
  account: walletClient.account,
@@ -2644,64 +2799,31 @@ var revokeAllACPs = async (walletClient, publicClient, revokerContract) => {
2644
2799
  }
2645
2800
  return walletClient.writeContract({
2646
2801
  address: revoker,
2647
- abi: ACP_VALIDATOR_ABI,
2802
+ abi: ACP_REVOKER_ABI,
2648
2803
  functionName: "revokeAllExisting",
2649
2804
  args: [],
2650
2805
  account: walletClient.account,
2651
2806
  chain: walletClient.chain
2652
2807
  });
2653
2808
  };
2809
+ var checkAccess = async (acp, publicClient, handle) => {
2810
+ if (acp.type === "sharing" && handle === void 0) {
2811
+ if (ACPUtils.isExpired(acp))
2812
+ return "expired";
2813
+ return await isACPRevoked(acp, publicClient) ? "revoked" : "valid";
2814
+ }
2815
+ return ACPUtils.checkAccessOnChain(acp, publicClient, handle);
2816
+ };
2654
2817
  var isACPRevoked = async (acp, publicClient) => {
2655
2818
  if (acp.revokerContract === viem.zeroAddress || acp.revokerData === 0)
2656
2819
  return false;
2657
2820
  return publicClient.readContract({
2658
2821
  address: acp.revokerContract,
2659
- abi: ACP_VALIDATOR_ABI,
2822
+ abi: ACP_REVOKER_ABI,
2660
2823
  functionName: "disabled",
2661
2824
  args: [acp.issuer, BigInt(acp.revokerData)]
2662
2825
  });
2663
2826
  };
2664
- var ACP_SHARE_REGISTRY_ABI = viem.parseAbi([
2665
- "struct ACP { address issuer; uint64 expiration; address recipient; uint256 revokerData; address revokerContract; uint8 scope; address[] contracts; bytes32[] handles; bytes32 sealingKey; bytes issuerSignature; bytes recipientSignature; }",
2666
- "function share(ACP calldata acp) external returns (bytes32)",
2667
- "function removeShare(bytes32 shareId) external",
2668
- "function sharesFor(address recipient) external view returns (ACP[] memory)",
2669
- "function getShare(bytes32 shareId) external view returns (ACP memory)",
2670
- "function isShareValid(bytes32 shareId) external view returns (bool)"
2671
- ]);
2672
- var ACP_TUPLE = [
2673
- {
2674
- type: "tuple",
2675
- components: [
2676
- { name: "issuer", type: "address" },
2677
- { name: "expiration", type: "uint64" },
2678
- { name: "recipient", type: "address" },
2679
- { name: "revokerData", type: "uint256" },
2680
- { name: "revokerContract", type: "address" },
2681
- { name: "scope", type: "uint8" },
2682
- { name: "contracts", type: "address[]" },
2683
- { name: "handles", type: "bytes32[]" },
2684
- { name: "sealingKey", type: "bytes32" },
2685
- { name: "issuerSignature", type: "bytes" },
2686
- { name: "recipientSignature", type: "bytes" }
2687
- ]
2688
- }
2689
- ];
2690
- var ZERO_BYTES32 = `0x${"0".repeat(64)}`;
2691
- var toChainShare = (acp) => {
2692
- const pub = ACPUtils.getPublic(acp, true);
2693
- return {
2694
- ...pub,
2695
- expiration: BigInt(pub.expiration),
2696
- revokerData: BigInt(pub.revokerData),
2697
- sealingKey: ZERO_BYTES32,
2698
- recipientSignature: "0x"
2699
- };
2700
- };
2701
- var computeShareId = (acp) => {
2702
- const p = toChainShare(acp);
2703
- return viem.keccak256(viem.encodeAbiParameters(ACP_TUPLE, [p]));
2704
- };
2705
2827
  var shareOnChain = async (acp, walletClient, registry) => {
2706
2828
  if (acp.type !== "sharing") {
2707
2829
  throw new Error(`Cannot share a '${acp.type}' ACP on-chain \u2014 only 'sharing' ACPs are shareable.`);
@@ -2732,7 +2854,7 @@ var getIncomingShares = async (publicClient, registry, recipient) => {
2732
2854
  args: [recipient]
2733
2855
  });
2734
2856
  return raw.map((s) => ({
2735
- shareId: viem.keccak256(viem.encodeAbiParameters(ACP_TUPLE, [s])),
2857
+ shareId: shareIdOfChainShare(s),
2736
2858
  issuer: s.issuer,
2737
2859
  expiration: Number(s.expiration),
2738
2860
  recipient: s.recipient,
@@ -2744,9 +2866,9 @@ var getIncomingShares = async (publicClient, registry, recipient) => {
2744
2866
  issuerSignature: s.issuerSignature
2745
2867
  }));
2746
2868
  };
2747
- var importFromChain = async (share, publicClient, walletClient) => {
2869
+ var importFromChain = async (share, publicClient, walletClient, importOptions = {}) => {
2748
2870
  const { shareId: _shareId, ...options } = share;
2749
- return importShared({ ...options, type: "sharing" }, publicClient, walletClient);
2871
+ return importShared({ ...options, type: "sharing" }, publicClient, walletClient, importOptions);
2750
2872
  };
2751
2873
  var removeShareOnChain = async (shareId, walletClient, registry) => {
2752
2874
  if (walletClient.account == null)
@@ -2784,6 +2906,7 @@ var acps = {
2784
2906
  revokeACP,
2785
2907
  revokeAllACPs,
2786
2908
  isACPRevoked,
2909
+ checkAccess,
2787
2910
  shareOnChain,
2788
2911
  getIncomingShares,
2789
2912
  importFromChain,
@@ -4496,7 +4619,7 @@ var buildDecryptResultHash = (ctHash, cleartext, chainId) => {
4496
4619
  async function verifyDecryptResult(handle, cleartext, signature, publicClient) {
4497
4620
  const chainId = publicClient.chain?.id ?? await publicClient.getChainId();
4498
4621
  const expectedSigner = await publicClient.readContract({
4499
- address: TASK_MANAGER_ADDRESS,
4622
+ address: await getTaskManagerAddress(publicClient, chainId),
4500
4623
  abi: decryptResultSignerAbi,
4501
4624
  functionName: "decryptResultSigner",
4502
4625
  args: []
@@ -4616,6 +4739,7 @@ function createCofheClientBase(opts) {
4616
4739
  zkBuilderAndCrsGenerator: opts.zkBuilderAndCrsGenerator,
4617
4740
  initTfhe: opts.initTfhe,
4618
4741
  zkProveWorkerFn: opts.zkProveWorkerFn,
4742
+ beforeMainThreadProve: opts.beforeMainThreadProve,
4619
4743
  keysStorage,
4620
4744
  requireConnected: _requireConnected
4621
4745
  });
@@ -4692,10 +4816,11 @@ function createCofheClientBase(opts) {
4692
4816
  walletClient
4693
4817
  );
4694
4818
  },
4695
- importShared: async (options, clients) => {
4819
+ importShared: async (options, importOptions = {}) => {
4696
4820
  _requireConnected();
4697
- const { publicClient, walletClient } = clients ?? connectStore.getState();
4698
- return acps.importShared(options, publicClient, walletClient);
4821
+ const { activate, ...clients } = importOptions;
4822
+ const { publicClient, walletClient } = clients.publicClient ? clients : connectStore.getState();
4823
+ return acps.importShared(options, publicClient, walletClient, { activate });
4699
4824
  },
4700
4825
  // Get or create methods (require connection)
4701
4826
  getOrCreateSelfACP: async (chainId, account, options) => {
@@ -4738,6 +4863,11 @@ function createCofheClientBase(opts) {
4738
4863
  const { publicClient } = connectStore.getState();
4739
4864
  return acps.isACPRevoked(acp, publicClient);
4740
4865
  },
4866
+ checkAccess: async (acp, handle) => {
4867
+ _requireConnected();
4868
+ const { publicClient } = connectStore.getState();
4869
+ return acps.checkAccess(acp, publicClient, handle);
4870
+ },
4741
4871
  // On-chain sharing (require connection + config.acp.sharingRegistry)
4742
4872
  shareOnChain: async (acp) => {
4743
4873
  _requireConnected();
@@ -4754,10 +4884,10 @@ function createCofheClientBase(opts) {
4754
4884
  const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
4755
4885
  return acps.getIncomingShares(publicClient, sharingRegistry, account);
4756
4886
  },
4757
- importFromChain: async (share) => {
4887
+ importFromChain: async (share, options) => {
4758
4888
  _requireConnected();
4759
4889
  const { publicClient, walletClient } = connectStore.getState();
4760
- return acps.importFromChain(share, publicClient, walletClient);
4890
+ return acps.importFromChain(share, publicClient, walletClient, options);
4761
4891
  },
4762
4892
  dismissShare: async (shareId) => {
4763
4893
  _requireConnected();
@@ -4867,7 +4997,7 @@ var createNodeStorage = () => {
4867
4997
  await fs.promises.writeFile(filePath, JSON.stringify(value));
4868
4998
  } catch (e) {
4869
4999
  console.warn("Node.js filesystem modules not available, falling back to memory storage" + e);
4870
- memoryStorage[name] = JSON.stringify(value);
5000
+ memoryStorage[name] = value;
4871
5001
  }
4872
5002
  },
4873
5003
  removeItem: async (name) => {
package/dist/node.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- import { C as CofheInputConfig, a as CofheConfig, b as CofheClient } from './clientTypes-CYZjFznO.cjs';
1
+ import { C as CofheInputConfig, a as CofheConfig, b as CofheClient } from './clientTypes-D3aIXmUp.cjs';
2
2
  import 'viem';
3
3
  import './types-C07FK-cL.cjs';
4
4
  import 'zod';
5
- import './acp-Wi6isVQI.cjs';
5
+ import './onchain-utils-CUAK8glx.cjs';
6
6
  import 'zustand/vanilla';
7
7
 
8
8
  /**
package/dist/node.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { C as CofheInputConfig, a as CofheConfig, b as CofheClient } from './clientTypes-BN3nbzYM.js';
1
+ import { C as CofheInputConfig, a as CofheConfig, b as CofheClient } from './clientTypes-5YPPR16m.js';
2
2
  import 'viem';
3
3
  import './types-C07FK-cL.js';
4
4
  import 'zod';
5
- import './acp-Wi6isVQI.js';
5
+ import './onchain-utils-CUAK8glx.js';
6
6
  import 'zustand/vanilla';
7
7
 
8
8
  /**
package/dist/node.js CHANGED
@@ -1,7 +1,7 @@
1
- import { createCofheConfigBase, createCofheClientBase } from './chunk-43USWPEH.js';
2
- import './chunk-N6IDQRRU.js';
3
- import './chunk-Q7CBWGQX.js';
4
- import { TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT } from './chunk-ESMZCFJY.js';
1
+ import { createCofheConfigBase, createCofheClientBase } from './chunk-GGI7Y6AW.js';
2
+ import './chunk-UKQAJK4N.js';
3
+ import './chunk-UJYOBHYA.js';
4
+ import { TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT } from './chunk-NMKMCAI3.js';
5
5
  import { promises } from 'fs';
6
6
  import { join } from 'path';
7
7
  import { init_panic_hook, ProvenCompactCiphertextList, CompactPkeCrs, TfheCompactPublicKey } from 'node-tfhe';
@@ -29,7 +29,7 @@ var createNodeStorage = () => {
29
29
  await promises.writeFile(filePath, JSON.stringify(value));
30
30
  } catch (e) {
31
31
  console.warn("Node.js filesystem modules not available, falling back to memory storage" + e);
32
- memoryStorage[name] = JSON.stringify(value);
32
+ memoryStorage[name] = value;
33
33
  }
34
34
  },
35
35
  removeItem: async (name) => {