@cofhe/sdk 0.2.0 → 0.3.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 (83) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/chains/defineChain.ts +2 -2
  3. package/chains/types.ts +3 -3
  4. package/core/baseBuilder.ts +18 -18
  5. package/core/client.test.ts +155 -41
  6. package/core/client.ts +72 -32
  7. package/core/clientTypes.ts +28 -18
  8. package/core/config.test.ts +40 -33
  9. package/core/config.ts +56 -51
  10. package/core/consts.ts +22 -0
  11. package/core/decrypt/{MockQueryDecrypterAbi.ts → MockThresholdNetworkAbi.ts} +71 -21
  12. package/core/decrypt/cofheMocksDecryptForTx.ts +142 -0
  13. package/core/decrypt/{cofheMocksSealOutput.ts → cofheMocksDecryptForView.ts} +12 -14
  14. package/core/decrypt/decryptForTxBuilder.ts +340 -0
  15. package/core/decrypt/{decryptHandleBuilder.ts → decryptForViewBuilder.ts} +75 -42
  16. package/core/decrypt/tnDecrypt.ts +232 -0
  17. package/core/decrypt/tnSealOutputV1.ts +5 -5
  18. package/core/decrypt/tnSealOutputV2.ts +27 -27
  19. package/core/encrypt/cofheMocksZkVerifySign.ts +19 -26
  20. package/core/encrypt/encryptInputsBuilder.test.ts +57 -61
  21. package/core/encrypt/encryptInputsBuilder.ts +65 -42
  22. package/core/encrypt/zkPackProveVerify.ts +11 -11
  23. package/core/error.ts +18 -18
  24. package/core/fetchKeys.test.ts +3 -3
  25. package/core/fetchKeys.ts +3 -3
  26. package/core/index.ts +22 -11
  27. package/core/permits.test.ts +5 -6
  28. package/core/permits.ts +5 -4
  29. package/core/utils.ts +10 -10
  30. package/dist/chains.cjs +4 -7
  31. package/dist/chains.d.cts +12 -12
  32. package/dist/chains.d.ts +12 -12
  33. package/dist/chains.js +1 -1
  34. package/dist/{chunk-WGCRJCBR.js → chunk-2TPSCOW3.js} +820 -224
  35. package/dist/{chunk-UGBVZNRT.js → chunk-NWDKXBIP.js} +309 -189
  36. package/dist/{chunk-WEAZ25JO.js → chunk-TBLR7NNE.js} +4 -7
  37. package/dist/{clientTypes-5_1nwtUe.d.cts → clientTypes-6aTZPQ_4.d.ts} +233 -173
  38. package/dist/{clientTypes-Es7fyi65.d.ts → clientTypes-Bhq7pCSA.d.cts} +233 -173
  39. package/dist/core.cjs +1138 -418
  40. package/dist/core.d.cts +37 -24
  41. package/dist/core.d.ts +37 -24
  42. package/dist/core.js +3 -3
  43. package/dist/node.cjs +1082 -370
  44. package/dist/node.d.cts +12 -12
  45. package/dist/node.d.ts +12 -12
  46. package/dist/node.js +8 -8
  47. package/dist/{permit-fUSe6KKq.d.cts → permit-MZ502UBl.d.cts} +30 -33
  48. package/dist/{permit-fUSe6KKq.d.ts → permit-MZ502UBl.d.ts} +30 -33
  49. package/dist/permits.cjs +305 -187
  50. package/dist/permits.d.cts +111 -812
  51. package/dist/permits.d.ts +111 -812
  52. package/dist/permits.js +1 -1
  53. package/dist/types-YiAC4gig.d.cts +33 -0
  54. package/dist/types-YiAC4gig.d.ts +33 -0
  55. package/dist/web.cjs +1085 -373
  56. package/dist/web.d.cts +13 -13
  57. package/dist/web.d.ts +13 -13
  58. package/dist/web.js +10 -10
  59. package/node/client.test.ts +34 -34
  60. package/node/config.test.ts +11 -11
  61. package/node/encryptInputs.test.ts +29 -29
  62. package/node/index.ts +15 -15
  63. package/package.json +3 -3
  64. package/permits/localstorage.test.ts +9 -13
  65. package/permits/onchain-utils.ts +221 -0
  66. package/permits/permit.test.ts +51 -5
  67. package/permits/permit.ts +28 -74
  68. package/permits/store.test.ts +10 -50
  69. package/permits/store.ts +4 -14
  70. package/permits/test-utils.ts +10 -2
  71. package/permits/types.ts +22 -9
  72. package/permits/utils.ts +0 -4
  73. package/permits/validation.test.ts +29 -32
  74. package/permits/validation.ts +112 -194
  75. package/web/client.web.test.ts +34 -34
  76. package/web/config.web.test.ts +11 -11
  77. package/web/encryptInputs.web.test.ts +29 -29
  78. package/web/index.ts +19 -19
  79. package/web/worker.builder.web.test.ts +28 -28
  80. package/web/worker.config.web.test.ts +47 -47
  81. package/web/worker.output.web.test.ts +10 -10
  82. package/dist/types-KImPrEIe.d.cts +0 -48
  83. package/dist/types-KImPrEIe.d.ts +0 -48
package/dist/core.cjs CHANGED
@@ -32,53 +32,53 @@ var nacl__namespace = /*#__PURE__*/_interopNamespace(nacl);
32
32
  // core/client.ts
33
33
 
34
34
  // core/error.ts
35
- var CofhesdkErrorCode = /* @__PURE__ */ ((CofhesdkErrorCode2) => {
36
- CofhesdkErrorCode2["InternalError"] = "INTERNAL_ERROR";
37
- CofhesdkErrorCode2["UnknownEnvironment"] = "UNKNOWN_ENVIRONMENT";
38
- CofhesdkErrorCode2["InitTfheFailed"] = "INIT_TFHE_FAILED";
39
- CofhesdkErrorCode2["InitViemFailed"] = "INIT_VIEM_FAILED";
40
- CofhesdkErrorCode2["InitEthersFailed"] = "INIT_ETHERS_FAILED";
41
- CofhesdkErrorCode2["NotConnected"] = "NOT_CONNECTED";
42
- CofhesdkErrorCode2["MissingPublicClient"] = "MISSING_PUBLIC_CLIENT";
43
- CofhesdkErrorCode2["MissingWalletClient"] = "MISSING_WALLET_CLIENT";
44
- CofhesdkErrorCode2["MissingProviderParam"] = "MISSING_PROVIDER_PARAM";
45
- CofhesdkErrorCode2["EmptySecurityZonesParam"] = "EMPTY_SECURITY_ZONES_PARAM";
46
- CofhesdkErrorCode2["InvalidPermitData"] = "INVALID_PERMIT_DATA";
47
- CofhesdkErrorCode2["InvalidPermitDomain"] = "INVALID_PERMIT_DOMAIN";
48
- CofhesdkErrorCode2["PermitNotFound"] = "PERMIT_NOT_FOUND";
49
- CofhesdkErrorCode2["CannotRemoveLastPermit"] = "CANNOT_REMOVE_LAST_PERMIT";
50
- CofhesdkErrorCode2["AccountUninitialized"] = "ACCOUNT_UNINITIALIZED";
51
- CofhesdkErrorCode2["ChainIdUninitialized"] = "CHAIN_ID_UNINITIALIZED";
52
- CofhesdkErrorCode2["SealOutputFailed"] = "SEAL_OUTPUT_FAILED";
53
- CofhesdkErrorCode2["SealOutputReturnedNull"] = "SEAL_OUTPUT_RETURNED_NULL";
54
- CofhesdkErrorCode2["InvalidUtype"] = "INVALID_UTYPE";
55
- CofhesdkErrorCode2["DecryptFailed"] = "DECRYPT_FAILED";
56
- CofhesdkErrorCode2["DecryptReturnedNull"] = "DECRYPT_RETURNED_NULL";
57
- CofhesdkErrorCode2["ZkMocksInsertCtHashesFailed"] = "ZK_MOCKS_INSERT_CT_HASHES_FAILED";
58
- CofhesdkErrorCode2["ZkMocksCalcCtHashesFailed"] = "ZK_MOCKS_CALC_CT_HASHES_FAILED";
59
- CofhesdkErrorCode2["ZkMocksVerifySignFailed"] = "ZK_MOCKS_VERIFY_SIGN_FAILED";
60
- CofhesdkErrorCode2["ZkMocksCreateProofSignatureFailed"] = "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED";
61
- CofhesdkErrorCode2["ZkVerifyFailed"] = "ZK_VERIFY_FAILED";
62
- CofhesdkErrorCode2["ZkPackFailed"] = "ZK_PACK_FAILED";
63
- CofhesdkErrorCode2["ZkProveFailed"] = "ZK_PROVE_FAILED";
64
- CofhesdkErrorCode2["EncryptRemainingInItems"] = "ENCRYPT_REMAINING_IN_ITEMS";
65
- CofhesdkErrorCode2["ZkUninitialized"] = "ZK_UNINITIALIZED";
66
- CofhesdkErrorCode2["ZkVerifierUrlUninitialized"] = "ZK_VERIFIER_URL_UNINITIALIZED";
67
- CofhesdkErrorCode2["ThresholdNetworkUrlUninitialized"] = "THRESHOLD_NETWORK_URL_UNINITIALIZED";
68
- CofhesdkErrorCode2["MissingConfig"] = "MISSING_CONFIG";
69
- CofhesdkErrorCode2["UnsupportedChain"] = "UNSUPPORTED_CHAIN";
70
- CofhesdkErrorCode2["MissingZkBuilderAndCrsGenerator"] = "MISSING_ZK_BUILDER_AND_CRS_GENERATOR";
71
- CofhesdkErrorCode2["MissingTfhePublicKeyDeserializer"] = "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER";
72
- CofhesdkErrorCode2["MissingCompactPkeCrsDeserializer"] = "MISSING_COMPACT_PKE_CRS_DESERIALIZER";
73
- CofhesdkErrorCode2["MissingFheKey"] = "MISSING_FHE_KEY";
74
- CofhesdkErrorCode2["MissingCrs"] = "MISSING_CRS";
75
- CofhesdkErrorCode2["FetchKeysFailed"] = "FETCH_KEYS_FAILED";
76
- CofhesdkErrorCode2["PublicWalletGetChainIdFailed"] = "PUBLIC_WALLET_GET_CHAIN_ID_FAILED";
77
- CofhesdkErrorCode2["PublicWalletGetAddressesFailed"] = "PUBLIC_WALLET_GET_ADDRESSES_FAILED";
78
- CofhesdkErrorCode2["RehydrateKeysStoreFailed"] = "REHYDRATE_KEYS_STORE_FAILED";
79
- return CofhesdkErrorCode2;
80
- })(CofhesdkErrorCode || {});
81
- var CofhesdkError = class _CofhesdkError extends Error {
35
+ var CofheErrorCode = /* @__PURE__ */ ((CofheErrorCode2) => {
36
+ CofheErrorCode2["InternalError"] = "INTERNAL_ERROR";
37
+ CofheErrorCode2["UnknownEnvironment"] = "UNKNOWN_ENVIRONMENT";
38
+ CofheErrorCode2["InitTfheFailed"] = "INIT_TFHE_FAILED";
39
+ CofheErrorCode2["InitViemFailed"] = "INIT_VIEM_FAILED";
40
+ CofheErrorCode2["InitEthersFailed"] = "INIT_ETHERS_FAILED";
41
+ CofheErrorCode2["NotConnected"] = "NOT_CONNECTED";
42
+ CofheErrorCode2["MissingPublicClient"] = "MISSING_PUBLIC_CLIENT";
43
+ CofheErrorCode2["MissingWalletClient"] = "MISSING_WALLET_CLIENT";
44
+ CofheErrorCode2["MissingProviderParam"] = "MISSING_PROVIDER_PARAM";
45
+ CofheErrorCode2["EmptySecurityZonesParam"] = "EMPTY_SECURITY_ZONES_PARAM";
46
+ CofheErrorCode2["InvalidPermitData"] = "INVALID_PERMIT_DATA";
47
+ CofheErrorCode2["InvalidPermitDomain"] = "INVALID_PERMIT_DOMAIN";
48
+ CofheErrorCode2["PermitNotFound"] = "PERMIT_NOT_FOUND";
49
+ CofheErrorCode2["CannotRemoveLastPermit"] = "CANNOT_REMOVE_LAST_PERMIT";
50
+ CofheErrorCode2["AccountUninitialized"] = "ACCOUNT_UNINITIALIZED";
51
+ CofheErrorCode2["ChainIdUninitialized"] = "CHAIN_ID_UNINITIALIZED";
52
+ CofheErrorCode2["SealOutputFailed"] = "SEAL_OUTPUT_FAILED";
53
+ CofheErrorCode2["SealOutputReturnedNull"] = "SEAL_OUTPUT_RETURNED_NULL";
54
+ CofheErrorCode2["InvalidUtype"] = "INVALID_UTYPE";
55
+ CofheErrorCode2["DecryptFailed"] = "DECRYPT_FAILED";
56
+ CofheErrorCode2["DecryptReturnedNull"] = "DECRYPT_RETURNED_NULL";
57
+ CofheErrorCode2["ZkMocksInsertCtHashesFailed"] = "ZK_MOCKS_INSERT_CT_HASHES_FAILED";
58
+ CofheErrorCode2["ZkMocksCalcCtHashesFailed"] = "ZK_MOCKS_CALC_CT_HASHES_FAILED";
59
+ CofheErrorCode2["ZkMocksVerifySignFailed"] = "ZK_MOCKS_VERIFY_SIGN_FAILED";
60
+ CofheErrorCode2["ZkMocksCreateProofSignatureFailed"] = "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED";
61
+ CofheErrorCode2["ZkVerifyFailed"] = "ZK_VERIFY_FAILED";
62
+ CofheErrorCode2["ZkPackFailed"] = "ZK_PACK_FAILED";
63
+ CofheErrorCode2["ZkProveFailed"] = "ZK_PROVE_FAILED";
64
+ CofheErrorCode2["EncryptRemainingInItems"] = "ENCRYPT_REMAINING_IN_ITEMS";
65
+ CofheErrorCode2["ZkUninitialized"] = "ZK_UNINITIALIZED";
66
+ CofheErrorCode2["ZkVerifierUrlUninitialized"] = "ZK_VERIFIER_URL_UNINITIALIZED";
67
+ CofheErrorCode2["ThresholdNetworkUrlUninitialized"] = "THRESHOLD_NETWORK_URL_UNINITIALIZED";
68
+ CofheErrorCode2["MissingConfig"] = "MISSING_CONFIG";
69
+ CofheErrorCode2["UnsupportedChain"] = "UNSUPPORTED_CHAIN";
70
+ CofheErrorCode2["MissingZkBuilderAndCrsGenerator"] = "MISSING_ZK_BUILDER_AND_CRS_GENERATOR";
71
+ CofheErrorCode2["MissingTfhePublicKeyDeserializer"] = "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER";
72
+ CofheErrorCode2["MissingCompactPkeCrsDeserializer"] = "MISSING_COMPACT_PKE_CRS_DESERIALIZER";
73
+ CofheErrorCode2["MissingFheKey"] = "MISSING_FHE_KEY";
74
+ CofheErrorCode2["MissingCrs"] = "MISSING_CRS";
75
+ CofheErrorCode2["FetchKeysFailed"] = "FETCH_KEYS_FAILED";
76
+ CofheErrorCode2["PublicWalletGetChainIdFailed"] = "PUBLIC_WALLET_GET_CHAIN_ID_FAILED";
77
+ CofheErrorCode2["PublicWalletGetAddressesFailed"] = "PUBLIC_WALLET_GET_ADDRESSES_FAILED";
78
+ CofheErrorCode2["RehydrateKeysStoreFailed"] = "REHYDRATE_KEYS_STORE_FAILED";
79
+ return CofheErrorCode2;
80
+ })(CofheErrorCode || {});
81
+ var CofheError = class _CofheError extends Error {
82
82
  code;
83
83
  cause;
84
84
  hint;
@@ -86,25 +86,25 @@ var CofhesdkError = class _CofhesdkError extends Error {
86
86
  constructor({ code, message, cause, hint, context }) {
87
87
  const fullMessage = cause ? `${message} | Caused by: ${cause.message}` : message;
88
88
  super(fullMessage);
89
- this.name = "CofhesdkError";
89
+ this.name = "CofheError";
90
90
  this.code = code;
91
91
  this.cause = cause;
92
92
  this.hint = hint;
93
93
  this.context = context;
94
94
  if (Error.captureStackTrace) {
95
- Error.captureStackTrace(this, _CofhesdkError);
95
+ Error.captureStackTrace(this, _CofheError);
96
96
  }
97
97
  }
98
98
  /**
99
- * Creates a CofhesdkError from an unknown error
100
- * If the error is a CofhesdkError, it is returned unchanged, else a new CofhesdkError is created
101
- * If a wrapperError is provided, it is used to create the new CofhesdkError, else a default is used
99
+ * Creates a CofheError from an unknown error
100
+ * If the error is a CofheError, it is returned unchanged, else a new CofheError is created
101
+ * If a wrapperError is provided, it is used to create the new CofheError, else a default is used
102
102
  */
103
103
  static fromError(error, wrapperError) {
104
- if (isCofhesdkError(error))
104
+ if (isCofheError(error))
105
105
  return error;
106
106
  const cause = error instanceof Error ? error : new Error(`${error}`);
107
- return new _CofhesdkError({
107
+ return new _CofheError({
108
108
  code: wrapperError?.code ?? "INTERNAL_ERROR" /* InternalError */,
109
109
  message: wrapperError?.message ?? "An internal error occurred",
110
110
  hint: wrapperError?.hint,
@@ -164,7 +164,7 @@ var bigintSafeJsonStringify = (value) => {
164
164
  return value2;
165
165
  });
166
166
  };
167
- var isCofhesdkError = (error) => error instanceof CofhesdkError;
167
+ var isCofheError = (error) => error instanceof CofheError;
168
168
 
169
169
  // core/types.ts
170
170
  var FheTypes = /* @__PURE__ */ ((FheTypes2) => {
@@ -315,14 +315,14 @@ async function getPublicClientChainID(publicClient) {
315
315
  try {
316
316
  chainId = publicClient.chain?.id ?? await publicClient.getChainId();
317
317
  } catch (e) {
318
- throw new CofhesdkError({
318
+ throw new CofheError({
319
319
  code: "PUBLIC_WALLET_GET_CHAIN_ID_FAILED" /* PublicWalletGetChainIdFailed */,
320
320
  message: "getting chain ID from public client failed",
321
321
  cause: e instanceof Error ? e : void 0
322
322
  });
323
323
  }
324
324
  if (chainId === null) {
325
- throw new CofhesdkError({
325
+ throw new CofheError({
326
326
  code: "PUBLIC_WALLET_GET_CHAIN_ID_FAILED" /* PublicWalletGetChainIdFailed */,
327
327
  message: "chain ID from public client is null"
328
328
  });
@@ -337,14 +337,14 @@ async function getWalletClientAccount(walletClient) {
337
337
  address = (await walletClient.getAddresses())?.[0];
338
338
  }
339
339
  } catch (e) {
340
- throw new CofhesdkError({
340
+ throw new CofheError({
341
341
  code: "PUBLIC_WALLET_GET_ADDRESSES_FAILED" /* PublicWalletGetAddressesFailed */,
342
342
  message: "getting address from wallet client failed",
343
343
  cause: e instanceof Error ? e : void 0
344
344
  });
345
345
  }
346
346
  if (!address) {
347
- throw new CofhesdkError({
347
+ throw new CofheError({
348
348
  code: "PUBLIC_WALLET_GET_ADDRESSES_FAILED" /* PublicWalletGetAddressesFailed */,
349
349
  message: "address from wallet client is null"
350
350
  });
@@ -448,7 +448,7 @@ var zkPack = (items, builder) => {
448
448
  break;
449
449
  }
450
450
  default: {
451
- throw new CofhesdkError({
451
+ throw new CofheError({
452
452
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
453
453
  message: `Invalid utype: ${item.utype}`,
454
454
  hint: `Ensure that the utype is valid, using the Encryptable type, for example: Encryptable.uint128(100n)`,
@@ -460,7 +460,7 @@ var zkPack = (items, builder) => {
460
460
  }
461
461
  }
462
462
  if (totalBits > MAX_ENCRYPTABLE_BITS) {
463
- throw new CofhesdkError({
463
+ throw new CofheError({
464
464
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
465
465
  message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
466
466
  hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
@@ -524,14 +524,14 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
524
524
  });
525
525
  if (!response.ok) {
526
526
  const errorBody = await response.text();
527
- throw new CofhesdkError({
527
+ throw new CofheError({
528
528
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
529
529
  message: `HTTP error! ZK proof verification failed - ${errorBody}`
530
530
  });
531
531
  }
532
532
  const json = await response.json();
533
533
  if (json.status !== "success") {
534
- throw new CofhesdkError({
534
+ throw new CofheError({
535
535
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
536
536
  message: `ZK proof verification response malformed - ${json.error}`
537
537
  });
@@ -543,7 +543,7 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
543
543
  };
544
544
  });
545
545
  } catch (e) {
546
- throw new CofhesdkError({
546
+ throw new CofheError({
547
547
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
548
548
  message: `ZK proof verification failed`,
549
549
  cause: e instanceof Error ? e : void 0
@@ -661,9 +661,17 @@ var MockZkVerifierAbi = [
661
661
  },
662
662
  { type: "error", name: "InvalidInputs", inputs: [] }
663
663
  ];
664
- var MocksZkVerifierAddress = "0x0000000000000000000000000000000000000100";
664
+
665
+ // core/consts.ts
666
+ var TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
667
+ var MOCKS_ZK_VERIFIER_ADDRESS = "0x0000000000000000000000000000000000005001";
668
+ var MOCKS_THRESHOLD_NETWORK_ADDRESS = "0x0000000000000000000000000000000000005002";
669
+ var TEST_BED_ADDRESS = "0x0000000000000000000000000000000000005003";
665
670
  var MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = "0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512";
666
671
  var MOCKS_ZK_VERIFIER_SIGNER_ADDRESS = "0x6E12D8C87503D4287c294f2Fdef96ACd9DFf6bd2";
672
+ var MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d";
673
+
674
+ // core/encrypt/cofheMocksZkVerifySign.ts
667
675
  function createMockZkVerifierSigner() {
668
676
  return viem.createWalletClient({
669
677
  chain: chains.hardhat,
@@ -706,7 +714,7 @@ async function cofheMocksCheckEncryptableBits(items) {
706
714
  }
707
715
  }
708
716
  if (totalBits > MAX_ENCRYPTABLE_BITS) {
709
- throw new CofhesdkError({
717
+ throw new CofheError({
710
718
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
711
719
  message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
712
720
  hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
@@ -729,18 +737,18 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
729
737
  let ctHashes;
730
738
  try {
731
739
  ctHashes = await publicClient.readContract({
732
- address: MocksZkVerifierAddress,
740
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
733
741
  abi: MockZkVerifierAbi,
734
742
  functionName: "zkVerifyCalcCtHashesPacked",
735
743
  args: calcCtHashesArgs
736
744
  });
737
745
  } catch (err) {
738
- throw new CofhesdkError({
746
+ throw new CofheError({
739
747
  code: "ZK_MOCKS_CALC_CT_HASHES_FAILED" /* ZkMocksCalcCtHashesFailed */,
740
748
  message: `mockZkVerifySign calcCtHashes failed while calling zkVerifyCalcCtHashesPacked`,
741
749
  cause: err instanceof Error ? err : void 0,
742
750
  context: {
743
- address: MocksZkVerifierAddress,
751
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
744
752
  items,
745
753
  account,
746
754
  securityZone,
@@ -750,7 +758,7 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
750
758
  });
751
759
  }
752
760
  if (ctHashes.length !== items.length) {
753
- throw new CofhesdkError({
761
+ throw new CofheError({
754
762
  code: "ZK_MOCKS_CALC_CT_HASHES_FAILED" /* ZkMocksCalcCtHashesFailed */,
755
763
  message: `mockZkVerifySign calcCtHashes returned incorrect number of ctHashes`,
756
764
  context: {
@@ -773,7 +781,7 @@ async function insertCtHashes(items, walletClient) {
773
781
  try {
774
782
  const account = walletClient.account;
775
783
  await walletClient.writeContract({
776
- address: MocksZkVerifierAddress,
784
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
777
785
  abi: MockZkVerifierAbi,
778
786
  functionName: "insertPackedCtHashes",
779
787
  args: insertPackedCtHashesArgs,
@@ -781,7 +789,7 @@ async function insertCtHashes(items, walletClient) {
781
789
  account
782
790
  });
783
791
  } catch (err) {
784
- throw new CofhesdkError({
792
+ throw new CofheError({
785
793
  code: "ZK_MOCKS_INSERT_CT_HASHES_FAILED" /* ZkMocksInsertCtHashesFailed */,
786
794
  message: `mockZkVerifySign insertPackedCtHashes failed while calling insertPackedCtHashes`,
787
795
  cause: err instanceof Error ? err : void 0,
@@ -799,7 +807,7 @@ async function createProofSignatures(items, securityZone) {
799
807
  try {
800
808
  encInputSignerClient = createMockZkVerifierSigner();
801
809
  } catch (err) {
802
- throw new CofhesdkError({
810
+ throw new CofheError({
803
811
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
804
812
  message: `mockZkVerifySign createProofSignatures failed while creating wallet client`,
805
813
  cause: err instanceof Error ? err : void 0,
@@ -820,7 +828,7 @@ async function createProofSignatures(items, securityZone) {
820
828
  signatures.push(signature);
821
829
  }
822
830
  } catch (err) {
823
- throw new CofhesdkError({
831
+ throw new CofheError({
824
832
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
825
833
  message: `mockZkVerifySign createProofSignatures failed while calling signMessage`,
826
834
  cause: err instanceof Error ? err : void 0,
@@ -831,7 +839,7 @@ async function createProofSignatures(items, securityZone) {
831
839
  });
832
840
  }
833
841
  if (signatures.length !== items.length) {
834
- throw new CofhesdkError({
842
+ throw new CofheError({
835
843
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
836
844
  message: `mockZkVerifySign createProofSignatures returned incorrect number of signatures`,
837
845
  context: {
@@ -861,21 +869,18 @@ var CofheChainSchema = zod.z.object({
861
869
  /** Network identifier */
862
870
  network: zod.z.string().min(1),
863
871
  /** coFhe service URL */
864
- coFheUrl: zod.z.string().url(),
872
+ coFheUrl: zod.z.url(),
865
873
  /** Verifier service URL */
866
- verifierUrl: zod.z.string().url(),
874
+ verifierUrl: zod.z.url(),
867
875
  /** Threshold network service URL */
868
- thresholdNetworkUrl: zod.z.string().url(),
876
+ thresholdNetworkUrl: zod.z.url(),
869
877
  /** Environment type */
870
878
  environment: EnvironmentSchema
871
879
  });
872
-
873
- // chains/defineChain.ts
874
880
  function defineChain(chainConfig) {
875
881
  const result = CofheChainSchema.safeParse(chainConfig);
876
882
  if (!result.success) {
877
- const errorMessages = result.error.errors.map((err) => `${err.path.join(".")}: ${err.message}`);
878
- throw new Error(`Invalid chain configuration: ${errorMessages.join(", ")}`);
883
+ throw new Error(`Invalid chain configuration: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
879
884
  }
880
885
  return result.data;
881
886
  }
@@ -891,46 +896,51 @@ var hardhat2 = defineChain({
891
896
  thresholdNetworkUrl: "http://127.0.0.1:3000",
892
897
  environment: "MOCK"
893
898
  });
894
- var CofhesdkConfigSchema = zod.z.object({
899
+ var CofheConfigSchema = zod.z.object({
895
900
  /** Environment that the SDK is running in */
896
901
  environment: zod.z.enum(["node", "hardhat", "web", "react"]).optional().default("node"),
897
902
  /** List of supported chain configurations */
898
903
  supportedChains: zod.z.array(zod.z.custom()),
899
- /** How permits are generated */
900
- permitGeneration: zod.z.enum(["ON_CONNECT", "ON_DECRYPT_HANDLES", "MANUAL"]).optional().default("ON_CONNECT"),
901
904
  /** Default permit expiration in seconds, default is 30 days */
902
905
  defaultPermitExpiration: zod.z.number().optional().default(60 * 60 * 24 * 30),
903
906
  /** Storage method for fhe keys (defaults to indexedDB on web, filesystem on node) */
904
907
  fheKeyStorage: zod.z.object({
905
- getItem: zod.z.function().args(zod.z.string()).returns(zod.z.promise(zod.z.any())),
906
- setItem: zod.z.function().args(zod.z.string(), zod.z.any()).returns(zod.z.promise(zod.z.void())),
907
- removeItem: zod.z.function().args(zod.z.string()).returns(zod.z.promise(zod.z.void()))
908
+ getItem: zod.z.custom((val) => typeof val === "function", {
909
+ message: "getItem must be a function"
910
+ }),
911
+ setItem: zod.z.custom((val) => typeof val === "function", {
912
+ message: "setItem must be a function"
913
+ }),
914
+ removeItem: zod.z.custom((val) => typeof val === "function", {
915
+ message: "removeItem must be a function"
916
+ })
908
917
  }).or(zod.z.null()).default(null),
909
918
  /** Whether to use Web Workers for ZK proof generation (web platform only) */
910
919
  useWorkers: zod.z.boolean().optional().default(true),
911
920
  /** Mocks configs */
912
921
  mocks: zod.z.object({
913
- sealOutputDelay: zod.z.number().optional().default(0)
914
- }).optional().default({ sealOutputDelay: 0 }),
922
+ decryptDelay: zod.z.number().optional().default(0),
923
+ encryptDelay: zod.z.union([zod.z.number(), zod.z.tuple([zod.z.number(), zod.z.number(), zod.z.number(), zod.z.number(), zod.z.number()])]).optional().default([100, 100, 100, 500, 500])
924
+ }).optional().default({ decryptDelay: 0, encryptDelay: [100, 100, 100, 500, 500] }),
915
925
  /** Internal configuration */
916
926
  _internal: zod.z.object({
917
927
  zkvWalletClient: zod.z.any().optional()
918
928
  }).optional()
919
929
  });
920
- function createCofhesdkConfigBase(config) {
921
- const result = CofhesdkConfigSchema.safeParse(config);
930
+ function createCofheConfigBase(config) {
931
+ const result = CofheConfigSchema.safeParse(config);
922
932
  if (!result.success) {
923
- throw new Error(`Invalid cofhesdk configuration: ${result.error.message}`);
933
+ throw new Error(`Invalid cofhe configuration: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
924
934
  }
925
935
  return result.data;
926
936
  }
927
- var getCofhesdkConfigItem = (config, key) => {
937
+ var getCofheConfigItem = (config, key) => {
928
938
  return config[key];
929
939
  };
930
940
  function getSupportedChainOrThrow(config, chainId) {
931
941
  const supportedChain = config.supportedChains.find((chain) => chain.id === chainId);
932
942
  if (!supportedChain) {
933
- throw new CofhesdkError({
943
+ throw new CofheError({
934
944
  code: "UNSUPPORTED_CHAIN" /* UnsupportedChain */,
935
945
  message: `Config does not support chain <${chainId}>`,
936
946
  hint: "Ensure config passed to client has been created with this chain in the config.supportedChains array.",
@@ -946,7 +956,7 @@ function getCoFheUrlOrThrow(config, chainId) {
946
956
  const supportedChain = getSupportedChainOrThrow(config, chainId);
947
957
  const url = supportedChain.coFheUrl;
948
958
  if (!url) {
949
- throw new CofhesdkError({
959
+ throw new CofheError({
950
960
  code: "MISSING_CONFIG" /* MissingConfig */,
951
961
  message: `CoFHE URL is not configured for chain <${chainId}>`,
952
962
  hint: "Ensure this chain config includes a coFheUrl property.",
@@ -959,7 +969,7 @@ function getZkVerifierUrlOrThrow(config, chainId) {
959
969
  const supportedChain = getSupportedChainOrThrow(config, chainId);
960
970
  const url = supportedChain.verifierUrl;
961
971
  if (!url) {
962
- throw new CofhesdkError({
972
+ throw new CofheError({
963
973
  code: "ZK_VERIFIER_URL_UNINITIALIZED" /* ZkVerifierUrlUninitialized */,
964
974
  message: `ZK verifier URL is not configured for chain <${chainId}>`,
965
975
  hint: "Ensure this chain config includes a verifierUrl property.",
@@ -972,7 +982,7 @@ function getThresholdNetworkUrlOrThrow(config, chainId) {
972
982
  const supportedChain = getSupportedChainOrThrow(config, chainId);
973
983
  const url = supportedChain.thresholdNetworkUrl;
974
984
  if (!url) {
975
- throw new CofhesdkError({
985
+ throw new CofheError({
976
986
  code: "THRESHOLD_NETWORK_URL_UNINITIALIZED" /* ThresholdNetworkUrlUninitialized */,
977
987
  message: `Threshold network URL is not configured for chain <${chainId}>`,
978
988
  hint: "Ensure this chain config includes a thresholdNetworkUrl property.",
@@ -1184,7 +1194,7 @@ var BaseBuilder = class {
1184
1194
  account;
1185
1195
  constructor(params) {
1186
1196
  if (!params.config) {
1187
- throw new CofhesdkError({
1197
+ throw new CofheError({
1188
1198
  code: "MISSING_CONFIG" /* MissingConfig */,
1189
1199
  message: "Builder config is undefined",
1190
1200
  hint: "Ensure client has been created with a config.",
@@ -1202,12 +1212,12 @@ var BaseBuilder = class {
1202
1212
  }
1203
1213
  /**
1204
1214
  * Asserts that this.chainId is populated
1205
- * @throws {CofhesdkError} If chainId is not set
1215
+ * @throws {CofheError} If chainId is not set
1206
1216
  */
1207
1217
  assertChainId() {
1208
1218
  if (this.chainId)
1209
1219
  return;
1210
- throw new CofhesdkError({
1220
+ throw new CofheError({
1211
1221
  code: "CHAIN_ID_UNINITIALIZED" /* ChainIdUninitialized */,
1212
1222
  message: "Chain ID is not set",
1213
1223
  hint: "Ensure client.connect() has been called and awaited, or use setChainId(...) to set the chainId explicitly.",
@@ -1218,12 +1228,12 @@ var BaseBuilder = class {
1218
1228
  }
1219
1229
  /**
1220
1230
  * Asserts that this.account is populated
1221
- * @throws {CofhesdkError} If account is not set
1231
+ * @throws {CofheError} If account is not set
1222
1232
  */
1223
1233
  assertAccount() {
1224
1234
  if (this.account)
1225
1235
  return;
1226
- throw new CofhesdkError({
1236
+ throw new CofheError({
1227
1237
  code: "ACCOUNT_UNINITIALIZED" /* AccountUninitialized */,
1228
1238
  message: "Account is not set",
1229
1239
  hint: "Ensure client.connect() has been called and awaited, or use setAccount(...) to set the account explicitly.",
@@ -1234,12 +1244,12 @@ var BaseBuilder = class {
1234
1244
  }
1235
1245
  /**
1236
1246
  * Asserts that this.publicClient is populated
1237
- * @throws {CofhesdkError} If publicClient is not set
1247
+ * @throws {CofheError} If publicClient is not set
1238
1248
  */
1239
1249
  assertPublicClient() {
1240
1250
  if (this.publicClient)
1241
1251
  return;
1242
- throw new CofhesdkError({
1252
+ throw new CofheError({
1243
1253
  code: "MISSING_PUBLIC_CLIENT" /* MissingPublicClient */,
1244
1254
  message: "Public client not found",
1245
1255
  hint: "Ensure client.connect() has been called with a publicClient.",
@@ -1250,12 +1260,12 @@ var BaseBuilder = class {
1250
1260
  }
1251
1261
  /**
1252
1262
  * Asserts that this.walletClient is populated
1253
- * @throws {CofhesdkError} If walletClient is not set
1263
+ * @throws {CofheError} If walletClient is not set
1254
1264
  */
1255
1265
  assertWalletClient() {
1256
1266
  if (this.walletClient)
1257
1267
  return;
1258
- throw new CofhesdkError({
1268
+ throw new CofheError({
1259
1269
  code: "MISSING_WALLET_CLIENT" /* MissingWalletClient */,
1260
1270
  message: "Wallet client not found",
1261
1271
  hint: "Ensure client.connect() has been called with a walletClient.",
@@ -1300,7 +1310,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1300
1310
  this.securityZone = params.securityZone ?? 0;
1301
1311
  this.zkvWalletClient = params.zkvWalletClient;
1302
1312
  if (!params.tfhePublicKeyDeserializer) {
1303
- throw new CofhesdkError({
1313
+ throw new CofheError({
1304
1314
  code: "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER" /* MissingTfhePublicKeyDeserializer */,
1305
1315
  message: "EncryptInputsBuilder tfhePublicKeyDeserializer is undefined",
1306
1316
  hint: "Ensure client has been created with a tfhePublicKeyDeserializer.",
@@ -1311,7 +1321,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1311
1321
  }
1312
1322
  this.tfhePublicKeyDeserializer = params.tfhePublicKeyDeserializer;
1313
1323
  if (!params.compactPkeCrsDeserializer) {
1314
- throw new CofhesdkError({
1324
+ throw new CofheError({
1315
1325
  code: "MISSING_COMPACT_PKE_CRS_DESERIALIZER" /* MissingCompactPkeCrsDeserializer */,
1316
1326
  message: "EncryptInputsBuilder compactPkeCrsDeserializer is undefined",
1317
1327
  hint: "Ensure client has been created with a compactPkeCrsDeserializer.",
@@ -1322,7 +1332,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1322
1332
  }
1323
1333
  this.compactPkeCrsDeserializer = params.compactPkeCrsDeserializer;
1324
1334
  if (!params.zkBuilderAndCrsGenerator) {
1325
- throw new CofhesdkError({
1335
+ throw new CofheError({
1326
1336
  code: "MISSING_ZK_BUILDER_AND_CRS_GENERATOR" /* MissingZkBuilderAndCrsGenerator */,
1327
1337
  message: "EncryptInputsBuilder zkBuilderAndCrsGenerator is undefined",
1328
1338
  hint: "Ensure client has been created with a zkBuilderAndCrsGenerator.",
@@ -1346,7 +1356,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1346
1356
  * ```typescript
1347
1357
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1348
1358
  * .setAccount("0x123")
1349
- * .encrypt();
1359
+ * .execute();
1350
1360
  * ```
1351
1361
  *
1352
1362
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1367,7 +1377,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1367
1377
  * ```typescript
1368
1378
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1369
1379
  * .setChainId(11155111)
1370
- * .encrypt();
1380
+ * .execute();
1371
1381
  * ```
1372
1382
  *
1373
1383
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1388,7 +1398,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1388
1398
  * ```typescript
1389
1399
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1390
1400
  * .setSecurityZone(1)
1391
- * .encrypt();
1401
+ * .execute();
1392
1402
  * ```
1393
1403
  *
1394
1404
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1409,7 +1419,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1409
1419
  * ```typescript
1410
1420
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1411
1421
  * .setUseWorker(false)
1412
- * .encrypt();
1422
+ * .execute();
1413
1423
  * ```
1414
1424
  *
1415
1425
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1443,13 +1453,13 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1443
1453
  * Example:
1444
1454
  * ```typescript
1445
1455
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1446
- * .setStepCallback((step: EncryptStep) => console.log(step))
1447
- * .encrypt();
1456
+ * .onStep((step: EncryptStep) => console.log(step))
1457
+ * .execute();
1448
1458
  * ```
1449
1459
  *
1450
1460
  * @returns The EncryptInputsBuilder instance.
1451
1461
  */
1452
- setStepCallback(callback) {
1462
+ onStep(callback) {
1453
1463
  this.stepCallback = callback;
1454
1464
  return this;
1455
1465
  }
@@ -1472,7 +1482,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1472
1482
  this.stepCallback(step, { ...context, isStart: false, isEnd: true, duration });
1473
1483
  }
1474
1484
  /**
1475
- * zkVerifierUrl is included in the chains exported from cofhesdk/chains for use in CofhesdkConfig.supportedChains
1485
+ * zkVerifierUrl is included in the chains exported from @cofhe/sdk/chains for use in CofheConfig.supportedChains
1476
1486
  * Users should generally not set this manually.
1477
1487
  */
1478
1488
  async getZkVerifierUrl() {
@@ -1480,7 +1490,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1480
1490
  return getZkVerifierUrlOrThrow(this.config, this.chainId);
1481
1491
  }
1482
1492
  /**
1483
- * initTfhe is a platform-specific dependency injected into core/createCofhesdkClientBase by web/createCofhesdkClient and node/createCofhesdkClient
1493
+ * initTfhe is a platform-specific dependency injected into core/createCofheClientBase by web/createCofheClient and node/createCofheClient
1484
1494
  * web/ uses zama "tfhe"
1485
1495
  * node/ uses zama "node-tfhe"
1486
1496
  * Users should not set this manually.
@@ -1491,7 +1501,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1491
1501
  try {
1492
1502
  return await this.initTfhe();
1493
1503
  } catch (error) {
1494
- throw CofhesdkError.fromError(error, {
1504
+ throw CofheError.fromError(error, {
1495
1505
  code: "INIT_TFHE_FAILED" /* InitTfheFailed */,
1496
1506
  message: `Failed to initialize TFHE`,
1497
1507
  context: {
@@ -1510,7 +1520,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1510
1520
  try {
1511
1521
  await this.keysStorage?.rehydrateKeysStore();
1512
1522
  } catch (error) {
1513
- throw CofhesdkError.fromError(error, {
1523
+ throw CofheError.fromError(error, {
1514
1524
  code: "REHYDRATE_KEYS_STORE_FAILED" /* RehydrateKeysStoreFailed */,
1515
1525
  message: `Failed to rehydrate keys store`,
1516
1526
  context: {
@@ -1532,7 +1542,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1532
1542
  this.keysStorage
1533
1543
  );
1534
1544
  } catch (error) {
1535
- throw CofhesdkError.fromError(error, {
1545
+ throw CofheError.fromError(error, {
1536
1546
  code: "FETCH_KEYS_FAILED" /* FetchKeysFailed */,
1537
1547
  message: `Failed to fetch FHE key and CRS`,
1538
1548
  context: {
@@ -1545,7 +1555,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1545
1555
  });
1546
1556
  }
1547
1557
  if (!fheKey) {
1548
- throw new CofhesdkError({
1558
+ throw new CofheError({
1549
1559
  code: "MISSING_FHE_KEY" /* MissingFheKey */,
1550
1560
  message: `FHE key not found`,
1551
1561
  context: {
@@ -1555,7 +1565,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1555
1565
  });
1556
1566
  }
1557
1567
  if (!crs) {
1558
- throw new CofhesdkError({
1568
+ throw new CofheError({
1559
1569
  code: "MISSING_CRS" /* MissingCrs */,
1560
1570
  message: `CRS not found for chainId <${this.chainId}>`,
1561
1571
  context: {
@@ -1565,6 +1575,17 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1565
1575
  }
1566
1576
  return { fheKey, fheKeyFetchedFromCoFHE, crs, crsFetchedFromCoFHE };
1567
1577
  }
1578
+ /**
1579
+ * Resolves the encryptDelay config into an array of 5 per-step delays.
1580
+ * A single number is broadcast to all steps; a tuple is used as-is.
1581
+ */
1582
+ resolveEncryptDelays() {
1583
+ const encryptDelay = this.config?.mocks?.encryptDelay ?? [100, 100, 100, 500, 500];
1584
+ if (typeof encryptDelay === "number") {
1585
+ return [encryptDelay, encryptDelay, encryptDelay, encryptDelay, encryptDelay];
1586
+ }
1587
+ return encryptDelay;
1588
+ }
1568
1589
  /**
1569
1590
  * @dev Encrypt against the cofheMocks instead of CoFHE
1570
1591
  *
@@ -1572,25 +1593,35 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1572
1593
  * cofheMocksInsertPackedHashes - stores the ctHashes and their plaintext values for on-chain mocking of FHE operations.
1573
1594
  * cofheMocksZkCreateProofSignatures - creates signatures to be included in the encrypted inputs. The signers address is known and verified in the mock contracts.
1574
1595
  */
1575
- async mocksEncrypt() {
1596
+ async mocksExecute() {
1576
1597
  this.assertAccount();
1577
1598
  this.assertPublicClient();
1578
1599
  this.assertWalletClient();
1600
+ const [initTfheDelay, fetchKeysDelay, packDelay, proveDelay, verifyDelay] = this.resolveEncryptDelays();
1579
1601
  this.fireStepStart("initTfhe" /* InitTfhe */);
1580
- await sleep(100);
1581
- this.fireStepEnd("initTfhe" /* InitTfhe */, { tfheInitializationExecuted: false });
1602
+ await sleep(initTfheDelay);
1603
+ this.fireStepEnd("initTfhe" /* InitTfhe */, {
1604
+ tfheInitializationExecuted: false,
1605
+ isMocks: true,
1606
+ mockSleep: initTfheDelay
1607
+ });
1582
1608
  this.fireStepStart("fetchKeys" /* FetchKeys */);
1583
- await sleep(100);
1584
- this.fireStepEnd("fetchKeys" /* FetchKeys */, { fheKeyFetchedFromCoFHE: false, crsFetchedFromCoFHE: false });
1609
+ await sleep(fetchKeysDelay);
1610
+ this.fireStepEnd("fetchKeys" /* FetchKeys */, {
1611
+ fheKeyFetchedFromCoFHE: false,
1612
+ crsFetchedFromCoFHE: false,
1613
+ isMocks: true,
1614
+ mockSleep: fetchKeysDelay
1615
+ });
1585
1616
  this.fireStepStart("pack" /* Pack */);
1586
1617
  await cofheMocksCheckEncryptableBits(this.inputItems);
1587
- await sleep(100);
1588
- this.fireStepEnd("pack" /* Pack */);
1618
+ await sleep(packDelay);
1619
+ this.fireStepEnd("pack" /* Pack */, { isMocks: true, mockSleep: packDelay });
1589
1620
  this.fireStepStart("prove" /* Prove */);
1590
- await sleep(500);
1591
- this.fireStepEnd("prove" /* Prove */);
1621
+ await sleep(proveDelay);
1622
+ this.fireStepEnd("prove" /* Prove */, { isMocks: true, mockSleep: proveDelay });
1592
1623
  this.fireStepStart("verify" /* Verify */);
1593
- await sleep(500);
1624
+ await sleep(verifyDelay);
1594
1625
  const signedResults = await cofheMocksZkVerifySign(
1595
1626
  this.inputItems,
1596
1627
  this.account,
@@ -1605,13 +1636,13 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1605
1636
  utype: this.inputItems[index].utype,
1606
1637
  signature
1607
1638
  }));
1608
- this.fireStepEnd("verify" /* Verify */);
1639
+ this.fireStepEnd("verify" /* Verify */, { isMocks: true, mockSleep: verifyDelay });
1609
1640
  return encryptedInputs;
1610
1641
  }
1611
1642
  /**
1612
1643
  * In the production context, perform a true encryption with the CoFHE coprocessor.
1613
1644
  */
1614
- async productionEncrypt() {
1645
+ async productionExecute() {
1615
1646
  this.assertAccount();
1616
1647
  this.assertChainId();
1617
1648
  this.fireStepStart("initTfhe" /* InitTfhe */);
@@ -1674,15 +1705,15 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1674
1705
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1675
1706
  * .setAccount('0x123...890') // optional
1676
1707
  * .setChainId(11155111) // optional
1677
- * .encrypt(); // execute
1708
+ * .execute(); // execute
1678
1709
  * ```
1679
1710
  *
1680
1711
  * @returns The encrypted inputs.
1681
1712
  */
1682
- async encrypt() {
1713
+ async execute() {
1683
1714
  if (this.chainId === chains.hardhat.id)
1684
- return this.mocksEncrypt();
1685
- return this.productionEncrypt();
1715
+ return this.mocksExecute();
1716
+ return this.productionExecute();
1686
1717
  }
1687
1718
  };
1688
1719
 
@@ -1733,9 +1764,6 @@ function isBigIntOrNumber(value) {
1733
1764
  }
1734
1765
  }
1735
1766
  }
1736
- function is0xPrefixed(value) {
1737
- return value.startsWith("0x");
1738
- }
1739
1767
 
1740
1768
  // permits/sealing.ts
1741
1769
  var PRIVATE_KEY_LENGTH = 64;
@@ -1823,158 +1851,137 @@ var SerializedSealingPair = zod.z.object({
1823
1851
  privateKey: zod.z.string(),
1824
1852
  publicKey: zod.z.string()
1825
1853
  });
1854
+ var addressSchema = zod.z.string().refine((val) => viem.isAddress(val), {
1855
+ error: "Invalid address"
1856
+ }).transform((val) => viem.getAddress(val));
1857
+ var addressNotZeroSchema = addressSchema.refine((val) => val !== viem.zeroAddress, {
1858
+ error: "Must not be zeroAddress"
1859
+ });
1860
+ var bytesSchema = zod.z.custom(
1861
+ (val) => {
1862
+ return typeof val === "string" && viem.isHex(val);
1863
+ },
1864
+ {
1865
+ message: "Invalid hex value"
1866
+ }
1867
+ );
1868
+ var bytesNotEmptySchema = bytesSchema.refine((val) => val !== "0x", {
1869
+ error: "Must not be empty"
1870
+ });
1826
1871
  var DEFAULT_EXPIRATION_FN = () => Math.round(Date.now() / 1e3) + 7 * 24 * 60 * 60;
1827
1872
  var zPermitWithDefaults = zod.z.object({
1828
1873
  name: zod.z.string().optional().default("Unnamed Permit"),
1829
1874
  type: zod.z.enum(["self", "sharing", "recipient"]),
1830
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1831
- message: "Permit issuer :: invalid address"
1832
- }).refine((val) => val !== viem.zeroAddress, {
1833
- message: "Permit issuer :: must not be zeroAddress"
1834
- }),
1835
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1836
- recipient: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1837
- message: "Permit recipient :: invalid address"
1838
- }),
1839
- validatorId: zod.z.number().optional().default(0),
1840
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1841
- message: "Permit validatorContract :: invalid address"
1842
- }),
1843
- issuerSignature: zod.z.string().optional().default("0x"),
1844
- recipientSignature: zod.z.string().optional().default("0x")
1875
+ issuer: addressNotZeroSchema,
1876
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1877
+ recipient: addressSchema.optional().default(viem.zeroAddress),
1878
+ validatorId: zod.z.int().optional().default(0),
1879
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1880
+ issuerSignature: bytesSchema.optional().default("0x"),
1881
+ recipientSignature: bytesSchema.optional().default("0x")
1845
1882
  });
1846
1883
  var zPermitWithSealingPair = zPermitWithDefaults.extend({
1847
1884
  sealingPair: SerializedSealingPair.optional()
1848
1885
  });
1849
- var ValidatorContractRefinement = [
1886
+ var ExternalValidatorRefinement = [
1850
1887
  (data) => data.validatorId !== 0 && data.validatorContract !== viem.zeroAddress || data.validatorId === 0 && data.validatorContract === viem.zeroAddress,
1851
1888
  {
1852
- message: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
1889
+ error: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
1853
1890
  path: ["validatorId", "validatorContract"]
1854
1891
  }
1855
1892
  ];
1893
+ var RecipientRefinement = [
1894
+ (data) => data.issuer !== data.recipient,
1895
+ {
1896
+ error: "Sharing permit :: issuer and recipient must not be the same",
1897
+ path: ["issuer", "recipient"]
1898
+ }
1899
+ ];
1856
1900
  var SelfPermitOptionsValidator = zod.z.object({
1857
1901
  type: zod.z.literal("self").optional().default("self"),
1858
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1859
- message: "Self permit issuer :: invalid address"
1860
- }).refine((val) => is0xPrefixed(val), {
1861
- message: "Self permit issuer :: must be 0x prefixed"
1862
- }).refine((val) => val !== viem.zeroAddress, {
1863
- message: "Self permit issuer :: must not be zeroAddress"
1864
- }),
1902
+ issuer: addressNotZeroSchema,
1865
1903
  name: zod.z.string().optional().default("Unnamed Permit"),
1866
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1867
- recipient: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1868
- message: "Self permit recipient :: invalid address"
1869
- }).refine((val) => is0xPrefixed(val), {
1870
- message: "Self permit recipient :: must be 0x prefixed"
1871
- }).refine((val) => val === viem.zeroAddress, {
1872
- message: "Self permit recipient :: must be zeroAddress"
1873
- }),
1874
- validatorId: zod.z.number().optional().default(0),
1875
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1876
- message: "Self permit validatorContract :: invalid address"
1877
- }),
1878
- issuerSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1879
- message: "Self permit issuerSignature :: must be 0x prefixed"
1880
- }),
1881
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1882
- message: "Self permit recipientSignature :: must be 0x prefixed"
1883
- })
1884
- }).refine(...ValidatorContractRefinement);
1904
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1905
+ recipient: addressSchema.optional().default(viem.zeroAddress),
1906
+ validatorId: zod.z.int().optional().default(0),
1907
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1908
+ issuerSignature: bytesSchema.optional().default("0x"),
1909
+ recipientSignature: bytesSchema.optional().default("0x")
1910
+ }).refine(...ExternalValidatorRefinement);
1885
1911
  var SelfPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "self", {
1886
- message: "Self permit :: type must be 'self'"
1912
+ error: "Type must be 'self'"
1887
1913
  }).refine((data) => data.recipient === viem.zeroAddress, {
1888
- message: "Self permit :: recipient must be zeroAddress"
1914
+ error: "Recipient must be zeroAddress"
1889
1915
  }).refine((data) => data.issuerSignature !== "0x", {
1890
- message: "Self permit :: issuerSignature must be populated"
1916
+ error: "IssuerSignature must be populated"
1891
1917
  }).refine((data) => data.recipientSignature === "0x", {
1892
- message: "Self permit :: recipientSignature must be empty"
1893
- }).refine(...ValidatorContractRefinement);
1918
+ error: "RecipientSignature must be empty"
1919
+ }).refine(...ExternalValidatorRefinement);
1894
1920
  var SharingPermitOptionsValidator = zod.z.object({
1895
1921
  type: zod.z.literal("sharing").optional().default("sharing"),
1896
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1897
- message: "Sharing permit issuer :: invalid address"
1898
- }).refine((val) => is0xPrefixed(val), {
1899
- message: "Sharing permit issuer :: must be 0x prefixed"
1900
- }).refine((val) => val !== viem.zeroAddress, {
1901
- message: "Sharing permit issuer :: must not be zeroAddress"
1902
- }),
1903
- recipient: zod.z.string().refine((val) => viem.isAddress(val), {
1904
- message: "Sharing permit recipient :: invalid address"
1905
- }).refine((val) => is0xPrefixed(val), {
1906
- message: "Sharing permit recipient :: must be 0x prefixed"
1907
- }).refine((val) => val !== viem.zeroAddress, {
1908
- message: "Sharing permit recipient :: must not be zeroAddress"
1909
- }),
1922
+ issuer: addressNotZeroSchema,
1923
+ recipient: addressNotZeroSchema,
1910
1924
  name: zod.z.string().optional().default("Unnamed Permit"),
1911
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1912
- validatorId: zod.z.number().optional().default(0),
1913
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1914
- message: "Sharing permit validatorContract :: invalid address"
1915
- }),
1916
- issuerSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1917
- message: "Sharing permit issuerSignature :: must be 0x prefixed"
1918
- }),
1919
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1920
- message: "Sharing permit recipientSignature :: must be 0x prefixed"
1921
- })
1922
- }).refine(...ValidatorContractRefinement);
1925
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1926
+ validatorId: zod.z.int().optional().default(0),
1927
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1928
+ issuerSignature: bytesSchema.optional().default("0x"),
1929
+ recipientSignature: bytesSchema.optional().default("0x")
1930
+ }).refine(...RecipientRefinement).refine(...ExternalValidatorRefinement);
1923
1931
  var SharingPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "sharing", {
1924
- message: "Sharing permit :: type must be 'sharing'"
1932
+ error: "Type must be 'sharing'"
1925
1933
  }).refine((data) => data.recipient !== viem.zeroAddress, {
1926
- message: "Sharing permit :: recipient must not be zeroAddress"
1934
+ error: "Recipient must not be zeroAddress"
1927
1935
  }).refine((data) => data.issuerSignature !== "0x", {
1928
- message: "Sharing permit :: issuerSignature must be populated"
1936
+ error: "IssuerSignature must be populated"
1929
1937
  }).refine((data) => data.recipientSignature === "0x", {
1930
- message: "Sharing permit :: recipientSignature must be empty"
1931
- }).refine(...ValidatorContractRefinement);
1938
+ error: "RecipientSignature must be empty"
1939
+ }).refine(...ExternalValidatorRefinement);
1932
1940
  var ImportPermitOptionsValidator = zod.z.object({
1933
1941
  type: zod.z.literal("recipient").optional().default("recipient"),
1934
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1935
- message: "Import permit issuer :: invalid address"
1936
- }).refine((val) => is0xPrefixed(val), {
1937
- message: "Import permit issuer :: must be 0x prefixed"
1938
- }).refine((val) => val !== viem.zeroAddress, {
1939
- message: "Import permit issuer :: must not be zeroAddress"
1940
- }),
1941
- recipient: zod.z.string().refine((val) => viem.isAddress(val), {
1942
- message: "Import permit recipient :: invalid address"
1943
- }).refine((val) => is0xPrefixed(val), {
1944
- message: "Import permit recipient :: must be 0x prefixed"
1945
- }).refine((val) => val !== viem.zeroAddress, {
1946
- message: "Import permit recipient :: must not be zeroAddress"
1947
- }),
1948
- issuerSignature: zod.z.string().refine((val) => is0xPrefixed(val), {
1949
- message: "Import permit issuerSignature :: must be 0x prefixed"
1950
- }).refine((val) => val !== "0x", {
1951
- message: "Import permit :: issuerSignature must be provided"
1952
- }),
1942
+ issuer: addressNotZeroSchema,
1943
+ recipient: addressNotZeroSchema,
1953
1944
  name: zod.z.string().optional().default("Unnamed Permit"),
1954
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1955
- validatorId: zod.z.number().optional().default(0),
1956
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1957
- message: "Import permit validatorContract :: invalid address"
1958
- }),
1959
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1960
- message: "Import permit recipientSignature :: must be 0x prefixed"
1961
- })
1962
- }).refine(...ValidatorContractRefinement);
1945
+ expiration: zod.z.int(),
1946
+ validatorId: zod.z.int().optional().default(0),
1947
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1948
+ issuerSignature: bytesNotEmptySchema,
1949
+ recipientSignature: bytesSchema.optional().default("0x")
1950
+ }).refine(...ExternalValidatorRefinement);
1963
1951
  var ImportPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "recipient", {
1964
- message: "Import permit :: type must be 'recipient'"
1952
+ error: "Type must be 'recipient'"
1965
1953
  }).refine((data) => data.recipient !== viem.zeroAddress, {
1966
- message: "Import permit :: recipient must not be zeroAddress"
1954
+ error: "Recipient must not be zeroAddress"
1967
1955
  }).refine((data) => data.issuerSignature !== "0x", {
1968
- message: "Import permit :: issuerSignature must be populated"
1956
+ error: "IssuerSignature must be populated"
1969
1957
  }).refine((data) => data.recipientSignature !== "0x", {
1970
- message: "Import permit :: recipientSignature must be populated"
1971
- }).refine(...ValidatorContractRefinement);
1972
- var validateSelfPermitOptions = (options) => SelfPermitOptionsValidator.safeParse(options);
1973
- var validateSharingPermitOptions = (options) => SharingPermitOptionsValidator.safeParse(options);
1974
- var validateImportPermitOptions = (options) => ImportPermitOptionsValidator.safeParse(options);
1975
- var validateSelfPermit = (permit) => SelfPermitValidator.safeParse(permit);
1976
- var validateSharingPermit = (permit) => SharingPermitValidator.safeParse(permit);
1977
- var validateImportPermit = (permit) => ImportPermitValidator.safeParse(permit);
1958
+ error: "RecipientSignature must be populated"
1959
+ }).refine(...ExternalValidatorRefinement);
1960
+ var safeParseAndThrowFormatted = (schema, data, message) => {
1961
+ const result = schema.safeParse(data);
1962
+ if (!result.success) {
1963
+ throw new Error(`${message}: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
1964
+ }
1965
+ return result.data;
1966
+ };
1967
+ var validateSelfPermitOptions = (options) => {
1968
+ return safeParseAndThrowFormatted(SelfPermitOptionsValidator, options, "Invalid self permit options");
1969
+ };
1970
+ var validateSharingPermitOptions = (options) => {
1971
+ return safeParseAndThrowFormatted(SharingPermitOptionsValidator, options, "Invalid sharing permit options");
1972
+ };
1973
+ var validateImportPermitOptions = (options) => {
1974
+ return safeParseAndThrowFormatted(ImportPermitOptionsValidator, options, "Invalid import permit options");
1975
+ };
1976
+ var validateSelfPermit = (permit) => {
1977
+ return safeParseAndThrowFormatted(SelfPermitValidator, permit, "Invalid self permit");
1978
+ };
1979
+ var validateSharingPermit = (permit) => {
1980
+ return safeParseAndThrowFormatted(SharingPermitValidator, permit, "Invalid sharing permit");
1981
+ };
1982
+ var validateImportPermit = (permit) => {
1983
+ return safeParseAndThrowFormatted(ImportPermitValidator, permit, "Invalid import permit");
1984
+ };
1978
1985
  var ValidationUtils = {
1979
1986
  /**
1980
1987
  * Check if permit is expired
@@ -2068,6 +2075,179 @@ var SignatureUtils = {
2068
2075
  throw new Error(`Unknown permit type: ${permitType}`);
2069
2076
  }
2070
2077
  };
2078
+ var getAclAddress = async (publicClient) => {
2079
+ const ACL_IFACE = "function acl() view returns (address)";
2080
+ const aclAbi = viem.parseAbi([ACL_IFACE]);
2081
+ return await publicClient.readContract({
2082
+ address: TASK_MANAGER_ADDRESS,
2083
+ abi: aclAbi,
2084
+ functionName: "acl"
2085
+ });
2086
+ };
2087
+ var getAclEIP712Domain = async (publicClient) => {
2088
+ const aclAddress = await getAclAddress(publicClient);
2089
+ const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
2090
+ const domainAbi = viem.parseAbi([EIP712_DOMAIN_IFACE]);
2091
+ const domain = await publicClient.readContract({
2092
+ address: aclAddress,
2093
+ abi: domainAbi,
2094
+ functionName: "eip712Domain"
2095
+ });
2096
+ const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
2097
+ return {
2098
+ name,
2099
+ version,
2100
+ chainId: Number(chainId),
2101
+ verifyingContract
2102
+ };
2103
+ };
2104
+ var checkPermitValidityOnChain = async (permission, publicClient) => {
2105
+ const aclAddress = await getAclAddress(publicClient);
2106
+ try {
2107
+ await publicClient.simulateContract({
2108
+ address: aclAddress,
2109
+ abi: checkPermitValidityAbi,
2110
+ functionName: "checkPermitValidity",
2111
+ args: [
2112
+ {
2113
+ issuer: permission.issuer,
2114
+ expiration: BigInt(permission.expiration),
2115
+ recipient: permission.recipient,
2116
+ validatorId: BigInt(permission.validatorId),
2117
+ validatorContract: permission.validatorContract,
2118
+ sealingKey: permission.sealingKey,
2119
+ issuerSignature: permission.issuerSignature,
2120
+ recipientSignature: permission.recipientSignature
2121
+ }
2122
+ ]
2123
+ });
2124
+ return true;
2125
+ } catch (err) {
2126
+ if (err instanceof viem.BaseError) {
2127
+ const revertError = err.walk((err2) => err2 instanceof viem.ContractFunctionRevertedError);
2128
+ if (revertError instanceof viem.ContractFunctionRevertedError) {
2129
+ const errorName = revertError.data?.errorName ?? "";
2130
+ throw new Error(errorName);
2131
+ }
2132
+ }
2133
+ const customErrorName = extractCustomErrorFromDetails(err, checkPermitValidityAbi);
2134
+ if (customErrorName) {
2135
+ throw new Error(customErrorName);
2136
+ }
2137
+ const hhDetailsData = extractReturnData(err);
2138
+ if (hhDetailsData != null) {
2139
+ const decoded = viem.decodeErrorResult({
2140
+ abi: checkPermitValidityAbi,
2141
+ data: hhDetailsData
2142
+ });
2143
+ throw new Error(decoded.errorName);
2144
+ }
2145
+ throw err;
2146
+ }
2147
+ };
2148
+ function extractCustomErrorFromDetails(err, abi) {
2149
+ const anyErr = err;
2150
+ const details = anyErr?.details ?? anyErr?.cause?.details;
2151
+ if (typeof details === "string") {
2152
+ const customErrorMatch = details.match(/reverted with custom error '(\w+)\(\)'/);
2153
+ if (customErrorMatch) {
2154
+ const errorName = customErrorMatch[1];
2155
+ const errorExists = abi.some((item) => item.type === "error" && item.name === errorName);
2156
+ if (errorExists) {
2157
+ return errorName;
2158
+ }
2159
+ }
2160
+ }
2161
+ return void 0;
2162
+ }
2163
+ function extractReturnData(err) {
2164
+ const anyErr = err;
2165
+ const s = anyErr?.details ?? anyErr?.cause?.details ?? anyErr?.shortMessage ?? anyErr?.message ?? String(err);
2166
+ return s.match(/return data:\s*(0x[a-fA-F0-9]+)/)?.[1];
2167
+ }
2168
+ var checkPermitValidityAbi = [
2169
+ {
2170
+ type: "function",
2171
+ name: "checkPermitValidity",
2172
+ inputs: [
2173
+ {
2174
+ name: "permission",
2175
+ type: "tuple",
2176
+ internalType: "struct Permission",
2177
+ components: [
2178
+ {
2179
+ name: "issuer",
2180
+ type: "address",
2181
+ internalType: "address"
2182
+ },
2183
+ {
2184
+ name: "expiration",
2185
+ type: "uint64",
2186
+ internalType: "uint64"
2187
+ },
2188
+ {
2189
+ name: "recipient",
2190
+ type: "address",
2191
+ internalType: "address"
2192
+ },
2193
+ {
2194
+ name: "validatorId",
2195
+ type: "uint256",
2196
+ internalType: "uint256"
2197
+ },
2198
+ {
2199
+ name: "validatorContract",
2200
+ type: "address",
2201
+ internalType: "address"
2202
+ },
2203
+ {
2204
+ name: "sealingKey",
2205
+ type: "bytes32",
2206
+ internalType: "bytes32"
2207
+ },
2208
+ {
2209
+ name: "issuerSignature",
2210
+ type: "bytes",
2211
+ internalType: "bytes"
2212
+ },
2213
+ {
2214
+ name: "recipientSignature",
2215
+ type: "bytes",
2216
+ internalType: "bytes"
2217
+ }
2218
+ ]
2219
+ }
2220
+ ],
2221
+ outputs: [
2222
+ {
2223
+ name: "",
2224
+ type: "bool",
2225
+ internalType: "bool"
2226
+ }
2227
+ ],
2228
+ stateMutability: "view"
2229
+ },
2230
+ {
2231
+ type: "error",
2232
+ name: "PermissionInvalid_Disabled",
2233
+ inputs: []
2234
+ },
2235
+ {
2236
+ type: "error",
2237
+ name: "PermissionInvalid_Expired",
2238
+ inputs: []
2239
+ },
2240
+ {
2241
+ type: "error",
2242
+ name: "PermissionInvalid_IssuerSignature",
2243
+ inputs: []
2244
+ },
2245
+ {
2246
+ type: "error",
2247
+ name: "PermissionInvalid_RecipientSignature",
2248
+ inputs: []
2249
+ }
2250
+ ];
2071
2251
 
2072
2252
  // permits/permit.ts
2073
2253
  var PermitUtils = {
@@ -2076,14 +2256,10 @@ var PermitUtils = {
2076
2256
  */
2077
2257
  createSelf: (options) => {
2078
2258
  const validation = validateSelfPermitOptions(options);
2079
- if (!validation.success) {
2080
- throw new Error(
2081
- "PermitUtils :: createSelf :: Parsing SelfPermitOptions failed " + JSON.stringify(validation.error, null, 2)
2082
- );
2083
- }
2084
2259
  const sealingPair = GenerateSealingKey();
2085
2260
  const permit = {
2086
- ...validation.data,
2261
+ hash: PermitUtils.getHash(validation),
2262
+ ...validation,
2087
2263
  sealingPair,
2088
2264
  _signedDomain: void 0
2089
2265
  };
@@ -2094,14 +2270,10 @@ var PermitUtils = {
2094
2270
  */
2095
2271
  createSharing: (options) => {
2096
2272
  const validation = validateSharingPermitOptions(options);
2097
- if (!validation.success) {
2098
- throw new Error(
2099
- "PermitUtils :: createSharing :: Parsing SharingPermitOptions failed " + JSON.stringify(validation.error, null, 2)
2100
- );
2101
- }
2102
2273
  const sealingPair = GenerateSealingKey();
2103
2274
  const permit = {
2104
- ...validation.data,
2275
+ hash: PermitUtils.getHash(validation),
2276
+ ...validation,
2105
2277
  sealingPair,
2106
2278
  _signedDomain: void 0
2107
2279
  };
@@ -2116,27 +2288,21 @@ var PermitUtils = {
2116
2288
  try {
2117
2289
  parsedOptions = JSON.parse(options);
2118
2290
  } catch (error) {
2119
- throw new Error(`PermitUtils :: importShared :: Failed to parse JSON string: ${error}`);
2291
+ throw new Error(`Failed to parse JSON string: ${error}`);
2120
2292
  }
2121
2293
  } else if (typeof options === "object" && options !== null) {
2122
2294
  parsedOptions = options;
2123
2295
  } else {
2124
- throw new Error(
2125
- "PermitUtils :: importShared :: Invalid input type, expected ImportSharedPermitOptions, object, or string"
2126
- );
2296
+ throw new Error("Invalid input type, expected ImportSharedPermitOptions, object, or string");
2127
2297
  }
2128
2298
  if (parsedOptions.type != null && parsedOptions.type !== "sharing") {
2129
- throw new Error(`PermitUtils :: importShared :: Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
2299
+ throw new Error(`Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
2130
2300
  }
2131
2301
  const validation = validateImportPermitOptions({ ...parsedOptions, type: "recipient" });
2132
- if (!validation.success) {
2133
- throw new Error(
2134
- "PermitUtils :: importShared :: Parsing ImportPermitOptions failed " + JSON.stringify(validation.error, null, 2)
2135
- );
2136
- }
2137
2302
  const sealingPair = GenerateSealingKey();
2138
2303
  const permit = {
2139
- ...validation.data,
2304
+ hash: PermitUtils.getHash(validation),
2305
+ ...validation,
2140
2306
  sealingPair,
2141
2307
  _signedDomain: void 0
2142
2308
  };
@@ -2148,11 +2314,11 @@ var PermitUtils = {
2148
2314
  sign: async (permit, publicClient, walletClient) => {
2149
2315
  if (walletClient == null || walletClient.account == null) {
2150
2316
  throw new Error(
2151
- "PermitUtils :: sign - walletClient undefined, you must pass in a `walletClient` for the connected user to create a permit signature"
2317
+ "Missing walletClient, you must pass in a `walletClient` for the connected user to create a permit signature"
2152
2318
  );
2153
2319
  }
2154
2320
  const primaryType = SignatureUtils.getPrimaryType(permit.type);
2155
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
2321
+ const domain = await getAclEIP712Domain(publicClient);
2156
2322
  const { types, message } = SignatureUtils.getSignatureParams(PermitUtils.getPermission(permit, true), primaryType);
2157
2323
  const signature = await walletClient.signTypedData({
2158
2324
  domain,
@@ -2212,6 +2378,7 @@ var PermitUtils = {
2212
2378
  */
2213
2379
  serialize: (permit) => {
2214
2380
  return {
2381
+ hash: permit.hash,
2215
2382
  name: permit.name,
2216
2383
  type: permit.type,
2217
2384
  issuer: permit.issuer,
@@ -2236,7 +2403,7 @@ var PermitUtils = {
2236
2403
  } else if (permit.type === "recipient") {
2237
2404
  return validateImportPermit(permit);
2238
2405
  } else {
2239
- throw new Error("PermitUtils :: validate :: Invalid permit type");
2406
+ throw new Error("Invalid permit type");
2240
2407
  }
2241
2408
  },
2242
2409
  /**
@@ -2244,12 +2411,7 @@ var PermitUtils = {
2244
2411
  */
2245
2412
  getPermission: (permit, skipValidation = false) => {
2246
2413
  if (!skipValidation) {
2247
- const validationResult = PermitUtils.validate(permit);
2248
- if (!validationResult.success) {
2249
- throw new Error(
2250
- `PermitUtils :: getPermission :: permit validation failed - ${JSON.stringify(validationResult.error, null, 2)} ${JSON.stringify(permit, null, 2)}`
2251
- );
2252
- }
2414
+ PermitUtils.validate(permit);
2253
2415
  }
2254
2416
  return {
2255
2417
  issuer: permit.issuer,
@@ -2330,28 +2492,7 @@ var PermitUtils = {
2330
2492
  * Fetch EIP712 domain from the blockchain
2331
2493
  */
2332
2494
  fetchEIP712Domain: async (publicClient) => {
2333
- const TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
2334
- const ACL_IFACE = "function acl() view returns (address)";
2335
- const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
2336
- const aclAbi = viem.parseAbi([ACL_IFACE]);
2337
- const aclAddress = await publicClient.readContract({
2338
- address: TASK_MANAGER_ADDRESS,
2339
- abi: aclAbi,
2340
- functionName: "acl"
2341
- });
2342
- const domainAbi = viem.parseAbi([EIP712_DOMAIN_IFACE]);
2343
- const domain = await publicClient.readContract({
2344
- address: aclAddress,
2345
- abi: domainAbi,
2346
- functionName: "eip712Domain"
2347
- });
2348
- const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
2349
- return {
2350
- name,
2351
- version,
2352
- chainId: Number(chainId),
2353
- verifyingContract
2354
- };
2495
+ return getAclEIP712Domain(publicClient);
2355
2496
  },
2356
2497
  /**
2357
2498
  * Check if permit's signed domain matches the provided domain
@@ -2365,8 +2506,15 @@ var PermitUtils = {
2365
2506
  checkSignedDomainValid: async (permit, publicClient) => {
2366
2507
  if (permit._signedDomain == null)
2367
2508
  return false;
2368
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
2509
+ const domain = await getAclEIP712Domain(publicClient);
2369
2510
  return PermitUtils.matchesDomain(permit, domain);
2511
+ },
2512
+ /**
2513
+ * Check if permit passes the on-chain validation
2514
+ */
2515
+ checkValidityOnChain: async (permit, publicClient) => {
2516
+ const permission = PermitUtils.getPermission(permit);
2517
+ return checkPermitValidityOnChain(permission, publicClient);
2370
2518
  }
2371
2519
  };
2372
2520
  var PERMIT_STORE_DEFAULTS = {
@@ -2420,11 +2568,11 @@ var setPermit = (chainId, account, permit) => {
2420
2568
  state.permits[chainId] = {};
2421
2569
  if (state.permits[chainId][account] == null)
2422
2570
  state.permits[chainId][account] = {};
2423
- state.permits[chainId][account][PermitUtils.getHash(permit)] = PermitUtils.serialize(permit);
2571
+ state.permits[chainId][account][permit.hash] = PermitUtils.serialize(permit);
2424
2572
  })
2425
2573
  );
2426
2574
  };
2427
- var removePermit = (chainId, account, hash, force) => {
2575
+ var removePermit = (chainId, account, hash) => {
2428
2576
  clearStaleStore();
2429
2577
  _permitStore.setState(
2430
2578
  immer.produce((state) => {
@@ -2438,15 +2586,7 @@ var removePermit = (chainId, account, hash, force) => {
2438
2586
  if (accountPermits[hash] == null)
2439
2587
  return;
2440
2588
  if (state.activePermitHash[chainId][account] === hash) {
2441
- const otherPermitHash = Object.keys(accountPermits).find((key) => key !== hash && accountPermits[key] != null);
2442
- if (otherPermitHash) {
2443
- state.activePermitHash[chainId][account] = otherPermitHash;
2444
- } else {
2445
- if (!force) {
2446
- throw new Error("Cannot remove the last permit without force flag");
2447
- }
2448
- state.activePermitHash[chainId][account] = void 0;
2449
- }
2589
+ state.activePermitHash[chainId][account] = void 0;
2450
2590
  }
2451
2591
  accountPermits[hash] = void 0;
2452
2592
  })
@@ -2497,7 +2637,7 @@ var storeActivePermit = async (permit, publicClient, walletClient) => {
2497
2637
  const chainId = await publicClient.getChainId();
2498
2638
  const account = walletClient.account.address;
2499
2639
  permitStore.setPermit(chainId, account, permit);
2500
- permitStore.setActivePermitHash(chainId, account, PermitUtils.getHash(permit));
2640
+ permitStore.setActivePermitHash(chainId, account, permit.hash);
2501
2641
  };
2502
2642
  var createPermitWithSign = async (options, publicClient, walletClient, permitMethod) => {
2503
2643
  const permit = await permitMethod(options, publicClient, walletClient);
@@ -2555,7 +2695,7 @@ var getOrCreateSharingPermit = async (publicClient, walletClient, options, chain
2555
2695
  }
2556
2696
  return createSharing(options, publicClient, walletClient);
2557
2697
  };
2558
- var removePermit2 = async (chainId, account, hash, force) => permitStore.removePermit(chainId, account, hash, force);
2698
+ var removePermit2 = async (chainId, account, hash) => permitStore.removePermit(chainId, account, hash);
2559
2699
  var removeActivePermit = async (chainId, account) => permitStore.removeActivePermitHash(chainId, account);
2560
2700
  var permits = {
2561
2701
  getSnapshot: permitStore.store.getState,
@@ -2595,8 +2735,8 @@ var convertViaUtype = (utype, value) => {
2595
2735
  }
2596
2736
  };
2597
2737
 
2598
- // core/decrypt/MockQueryDecrypterAbi.ts
2599
- var MockQueryDecrypterAbi = [
2738
+ // core/decrypt/MockThresholdNetworkAbi.ts
2739
+ var MockThresholdNetworkAbi = [
2600
2740
  {
2601
2741
  type: "function",
2602
2742
  name: "acl",
@@ -2643,11 +2783,7 @@ var MockQueryDecrypterAbi = [
2643
2783
  { name: "expiration", type: "uint64", internalType: "uint64" },
2644
2784
  { name: "recipient", type: "address", internalType: "address" },
2645
2785
  { name: "validatorId", type: "uint256", internalType: "uint256" },
2646
- {
2647
- name: "validatorContract",
2648
- type: "address",
2649
- internalType: "address"
2650
- },
2786
+ { name: "validatorContract", type: "address", internalType: "address" },
2651
2787
  { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2652
2788
  { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2653
2789
  { name: "recipientSignature", type: "bytes", internalType: "bytes" }
@@ -2676,11 +2812,7 @@ var MockQueryDecrypterAbi = [
2676
2812
  { name: "expiration", type: "uint64", internalType: "uint64" },
2677
2813
  { name: "recipient", type: "address", internalType: "address" },
2678
2814
  { name: "validatorId", type: "uint256", internalType: "uint256" },
2679
- {
2680
- name: "validatorContract",
2681
- type: "address",
2682
- internalType: "address"
2683
- },
2815
+ { name: "validatorContract", type: "address", internalType: "address" },
2684
2816
  { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2685
2817
  { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2686
2818
  { name: "recipientSignature", type: "bytes", internalType: "bytes" }
@@ -2704,13 +2836,6 @@ var MockQueryDecrypterAbi = [
2704
2836
  outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
2705
2837
  stateMutability: "pure"
2706
2838
  },
2707
- {
2708
- type: "function",
2709
- name: "taskManager",
2710
- inputs: [],
2711
- outputs: [{ name: "", type: "address", internalType: "contract TaskManager" }],
2712
- stateMutability: "view"
2713
- },
2714
2839
  {
2715
2840
  type: "function",
2716
2841
  name: "unseal",
@@ -2721,16 +2846,80 @@ var MockQueryDecrypterAbi = [
2721
2846
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
2722
2847
  stateMutability: "pure"
2723
2848
  },
2724
- { type: "error", name: "NotAllowed", inputs: [] },
2725
- { type: "error", name: "SealingKeyInvalid", inputs: [] },
2726
- { type: "error", name: "SealingKeyMissing", inputs: [] }
2849
+ {
2850
+ type: "function",
2851
+ name: "mockAcl",
2852
+ inputs: [],
2853
+ outputs: [{ name: "", type: "address", internalType: "contract MockACL" }],
2854
+ stateMutability: "view"
2855
+ },
2856
+ {
2857
+ type: "function",
2858
+ name: "mockTaskManager",
2859
+ inputs: [],
2860
+ outputs: [{ name: "", type: "address", internalType: "contract MockTaskManager" }],
2861
+ stateMutability: "view"
2862
+ },
2863
+ {
2864
+ type: "function",
2865
+ name: "mockQueryDecrypt",
2866
+ inputs: [
2867
+ { name: "ctHash", type: "uint256", internalType: "uint256" },
2868
+ { name: "", type: "uint256", internalType: "uint256" },
2869
+ { name: "issuer", type: "address", internalType: "address" }
2870
+ ],
2871
+ outputs: [
2872
+ { name: "allowed", type: "bool", internalType: "bool" },
2873
+ { name: "error", type: "string", internalType: "string" },
2874
+ { name: "", type: "uint256", internalType: "uint256" }
2875
+ ],
2876
+ stateMutability: "view"
2877
+ },
2878
+ {
2879
+ type: "function",
2880
+ name: "decryptForTxWithPermit",
2881
+ inputs: [
2882
+ { name: "ctHash", type: "uint256", internalType: "uint256" },
2883
+ {
2884
+ name: "permission",
2885
+ type: "tuple",
2886
+ internalType: "struct Permission",
2887
+ components: [
2888
+ { name: "issuer", type: "address", internalType: "address" },
2889
+ { name: "expiration", type: "uint64", internalType: "uint64" },
2890
+ { name: "recipient", type: "address", internalType: "address" },
2891
+ { name: "validatorId", type: "uint256", internalType: "uint256" },
2892
+ { name: "validatorContract", type: "address", internalType: "address" },
2893
+ { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2894
+ { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2895
+ { name: "recipientSignature", type: "bytes", internalType: "bytes" }
2896
+ ]
2897
+ }
2898
+ ],
2899
+ outputs: [
2900
+ { name: "allowed", type: "bool", internalType: "bool" },
2901
+ { name: "error", type: "string", internalType: "string" },
2902
+ { name: "decryptedValue", type: "uint256", internalType: "uint256" }
2903
+ ],
2904
+ stateMutability: "view"
2905
+ },
2906
+ {
2907
+ type: "function",
2908
+ name: "decryptForTxWithoutPermit",
2909
+ inputs: [{ name: "ctHash", type: "uint256", internalType: "uint256" }],
2910
+ outputs: [
2911
+ { name: "allowed", type: "bool", internalType: "bool" },
2912
+ { name: "error", type: "string", internalType: "string" },
2913
+ { name: "decryptedValue", type: "uint256", internalType: "uint256" }
2914
+ ],
2915
+ stateMutability: "view"
2916
+ }
2727
2917
  ];
2728
2918
 
2729
- // core/decrypt/cofheMocksSealOutput.ts
2730
- var MockQueryDecrypterAddress = "0x0000000000000000000000000000000000000200";
2731
- async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSealOutputDelay) {
2732
- if (mocksSealOutputDelay > 0)
2733
- await sleep(mocksSealOutputDelay);
2919
+ // core/decrypt/cofheMocksDecryptForView.ts
2920
+ async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient, mocksDecryptDelay) {
2921
+ if (mocksDecryptDelay > 0)
2922
+ await sleep(mocksDecryptDelay);
2734
2923
  const permission = PermitUtils.getPermission(permit, true);
2735
2924
  const permissionWithBigInts = {
2736
2925
  ...permission,
@@ -2738,19 +2927,19 @@ async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSe
2738
2927
  validatorId: BigInt(permission.validatorId)
2739
2928
  };
2740
2929
  const [allowed, error, result] = await publicClient.readContract({
2741
- address: MockQueryDecrypterAddress,
2742
- abi: MockQueryDecrypterAbi,
2930
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
2931
+ abi: MockThresholdNetworkAbi,
2743
2932
  functionName: "querySealOutput",
2744
2933
  args: [ctHash, BigInt(utype), permissionWithBigInts]
2745
2934
  });
2746
2935
  if (error != "") {
2747
- throw new CofhesdkError({
2936
+ throw new CofheError({
2748
2937
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2749
2938
  message: `mocks querySealOutput call failed: ${error}`
2750
2939
  });
2751
2940
  }
2752
2941
  if (allowed == false) {
2753
- throw new CofhesdkError({
2942
+ throw new CofheError({
2754
2943
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2755
2944
  message: `mocks querySealOutput call failed: ACL Access Denied (NotAllowed)`
2756
2945
  });
@@ -2769,7 +2958,7 @@ function numberArrayToUint8Array(arr) {
2769
2958
  }
2770
2959
  function convertSealedData(sealed) {
2771
2960
  if (!sealed) {
2772
- throw new CofhesdkError({
2961
+ throw new CofheError({
2773
2962
  code: "SEAL_OUTPUT_RETURNED_NULL" /* SealOutputReturnedNull */,
2774
2963
  message: "Sealed data is missing from completed response"
2775
2964
  });
@@ -2796,7 +2985,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2796
2985
  body: JSON.stringify(body)
2797
2986
  });
2798
2987
  } catch (e) {
2799
- throw new CofhesdkError({
2988
+ throw new CofheError({
2800
2989
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2801
2990
  message: `sealOutput request failed`,
2802
2991
  hint: "Ensure the threshold network URL is valid and reachable.",
@@ -2815,7 +3004,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2815
3004
  } catch {
2816
3005
  errorMessage = response.statusText || errorMessage;
2817
3006
  }
2818
- throw new CofhesdkError({
3007
+ throw new CofheError({
2819
3008
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2820
3009
  message: `sealOutput request failed: ${errorMessage}`,
2821
3010
  hint: "Check the threshold network URL and request parameters.",
@@ -2831,7 +3020,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2831
3020
  try {
2832
3021
  submitResponse = await response.json();
2833
3022
  } catch (e) {
2834
- throw new CofhesdkError({
3023
+ throw new CofheError({
2835
3024
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2836
3025
  message: `Failed to parse sealOutput submit response`,
2837
3026
  cause: e instanceof Error ? e : void 0,
@@ -2842,7 +3031,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2842
3031
  });
2843
3032
  }
2844
3033
  if (!submitResponse.request_id) {
2845
- throw new CofhesdkError({
3034
+ throw new CofheError({
2846
3035
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2847
3036
  message: `sealOutput submit response missing request_id`,
2848
3037
  context: {
@@ -2859,7 +3048,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2859
3048
  let completed = false;
2860
3049
  while (!completed) {
2861
3050
  if (Date.now() - startTime > POLL_TIMEOUT_MS) {
2862
- throw new CofhesdkError({
3051
+ throw new CofheError({
2863
3052
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2864
3053
  message: `sealOutput polling timed out after ${POLL_TIMEOUT_MS}ms`,
2865
3054
  hint: "The request may still be processing. Try again later.",
@@ -2879,7 +3068,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2879
3068
  }
2880
3069
  });
2881
3070
  } catch (e) {
2882
- throw new CofhesdkError({
3071
+ throw new CofheError({
2883
3072
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2884
3073
  message: `sealOutput status poll failed`,
2885
3074
  hint: "Ensure the threshold network URL is valid and reachable.",
@@ -2891,7 +3080,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2891
3080
  });
2892
3081
  }
2893
3082
  if (response.status === 404) {
2894
- throw new CofhesdkError({
3083
+ throw new CofheError({
2895
3084
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2896
3085
  message: `sealOutput request not found: ${requestId}`,
2897
3086
  hint: "The request may have expired or been invalid.",
@@ -2909,7 +3098,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2909
3098
  } catch {
2910
3099
  errorMessage = response.statusText || errorMessage;
2911
3100
  }
2912
- throw new CofhesdkError({
3101
+ throw new CofheError({
2913
3102
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2914
3103
  message: `sealOutput status poll failed: ${errorMessage}`,
2915
3104
  context: {
@@ -2924,7 +3113,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2924
3113
  try {
2925
3114
  statusResponse = await response.json();
2926
3115
  } catch (e) {
2927
- throw new CofhesdkError({
3116
+ throw new CofheError({
2928
3117
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2929
3118
  message: `Failed to parse sealOutput status response`,
2930
3119
  cause: e instanceof Error ? e : void 0,
@@ -2937,7 +3126,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2937
3126
  if (statusResponse.status === "COMPLETED") {
2938
3127
  if (statusResponse.is_succeed === false) {
2939
3128
  const errorMessage = statusResponse.error_message || "Unknown error";
2940
- throw new CofhesdkError({
3129
+ throw new CofheError({
2941
3130
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2942
3131
  message: `sealOutput request failed: ${errorMessage}`,
2943
3132
  context: {
@@ -2948,7 +3137,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2948
3137
  });
2949
3138
  }
2950
3139
  if (!statusResponse.sealed) {
2951
- throw new CofhesdkError({
3140
+ throw new CofheError({
2952
3141
  code: "SEAL_OUTPUT_RETURNED_NULL" /* SealOutputReturnedNull */,
2953
3142
  message: `sealOutput request completed but returned no sealed data`,
2954
3143
  context: {
@@ -2962,7 +3151,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2962
3151
  }
2963
3152
  await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
2964
3153
  }
2965
- throw new CofhesdkError({
3154
+ throw new CofheError({
2966
3155
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2967
3156
  message: "Polling loop exited unexpectedly",
2968
3157
  context: {
@@ -2975,9 +3164,99 @@ async function tnSealOutputV2(ctHash, chainId, permission, thresholdNetworkUrl)
2975
3164
  const requestId = await submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission);
2976
3165
  return await pollSealOutputStatus(thresholdNetworkUrl, requestId);
2977
3166
  }
3167
+ async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient, mocksDecryptForTxDelay) {
3168
+ if (mocksDecryptForTxDelay > 0)
3169
+ await sleep(mocksDecryptForTxDelay);
3170
+ if (permit !== null) {
3171
+ let permission = PermitUtils.getPermission(permit, true);
3172
+ const permissionWithBigInts = {
3173
+ ...permission,
3174
+ expiration: BigInt(permission.expiration),
3175
+ validatorId: BigInt(permission.validatorId)
3176
+ };
3177
+ const [allowed2, error2, result2] = await publicClient.readContract({
3178
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
3179
+ abi: MockThresholdNetworkAbi,
3180
+ functionName: "decryptForTxWithPermit",
3181
+ args: [ctHash, permissionWithBigInts]
3182
+ });
3183
+ if (error2 != "") {
3184
+ throw new CofheError({
3185
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3186
+ message: `mocks decryptForTx call failed: ${error2}`
3187
+ });
3188
+ }
3189
+ if (allowed2 == false) {
3190
+ throw new CofheError({
3191
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3192
+ message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
3193
+ });
3194
+ }
3195
+ const chainId2 = await publicClient.getChainId();
3196
+ const ctHashBigInt2 = BigInt(ctHash);
3197
+ const resultBigInt2 = BigInt(result2);
3198
+ const encryptionType2 = Number((ctHashBigInt2 & 0x7fn << 8n) >> 8n);
3199
+ const ctHashBytes322 = viem.pad(viem.toHex(ctHashBigInt2), { size: 32 });
3200
+ const packed2 = viem.encodePacked(
3201
+ ["uint256", "uint32", "uint64", "bytes32"],
3202
+ [resultBigInt2, encryptionType2, BigInt(chainId2), ctHashBytes322]
3203
+ );
3204
+ const messageHash2 = viem.keccak256(packed2);
3205
+ const signatureHex2 = await accounts.sign({
3206
+ hash: messageHash2,
3207
+ privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
3208
+ to: "hex"
3209
+ });
3210
+ const signature2 = signatureHex2.slice(2);
3211
+ return {
3212
+ ctHash,
3213
+ decryptedValue: BigInt(result2),
3214
+ signature: signature2
3215
+ };
3216
+ }
3217
+ const [allowed, error, result] = await publicClient.readContract({
3218
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
3219
+ abi: MockThresholdNetworkAbi,
3220
+ functionName: "decryptForTxWithoutPermit",
3221
+ args: [ctHash]
3222
+ });
3223
+ if (error != "") {
3224
+ throw new CofheError({
3225
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3226
+ message: `mocks decryptForTx call failed: ${error}`
3227
+ });
3228
+ }
3229
+ if (allowed == false) {
3230
+ throw new CofheError({
3231
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3232
+ message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
3233
+ });
3234
+ }
3235
+ const chainId = await publicClient.getChainId();
3236
+ const ctHashBigInt = BigInt(ctHash);
3237
+ const resultBigInt = BigInt(result);
3238
+ const encryptionType = Number((ctHashBigInt & 0x7fn << 8n) >> 8n);
3239
+ const ctHashBytes32 = viem.pad(viem.toHex(ctHashBigInt), { size: 32 });
3240
+ const packed = viem.encodePacked(
3241
+ ["uint256", "uint32", "uint64", "bytes32"],
3242
+ [resultBigInt, encryptionType, BigInt(chainId), ctHashBytes32]
3243
+ );
3244
+ const messageHash = viem.keccak256(packed);
3245
+ const signatureHex = await accounts.sign({
3246
+ hash: messageHash,
3247
+ privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
3248
+ to: "hex"
3249
+ });
3250
+ const signature = signatureHex.slice(2);
3251
+ return {
3252
+ ctHash,
3253
+ decryptedValue: BigInt(result),
3254
+ signature
3255
+ };
3256
+ }
2978
3257
 
2979
- // core/decrypt/decryptHandleBuilder.ts
2980
- var DecryptHandlesBuilder = class extends BaseBuilder {
3258
+ // core/decrypt/decryptForViewBuilder.ts
3259
+ var DecryptForViewBuilder = class extends BaseBuilder {
2981
3260
  ctHash;
2982
3261
  utype;
2983
3262
  permitHash;
@@ -3003,12 +3282,12 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3003
3282
  *
3004
3283
  * Example:
3005
3284
  * ```typescript
3006
- * const unsealed = await decryptHandle(ctHash, utype)
3285
+ * const unsealed = await client.decryptForView(ctHash, utype)
3007
3286
  * .setChainId(11155111)
3008
- * .decrypt();
3287
+ * .execute();
3009
3288
  * ```
3010
3289
  *
3011
- * @returns The chainable DecryptHandlesBuilder instance.
3290
+ * @returns The chainable DecryptForViewBuilder instance.
3012
3291
  */
3013
3292
  setChainId(chainId) {
3014
3293
  this.chainId = chainId;
@@ -3024,12 +3303,12 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3024
3303
  *
3025
3304
  * Example:
3026
3305
  * ```typescript
3027
- * const unsealed = await decryptHandle(ctHash, utype)
3306
+ * const unsealed = await client.decryptForView(ctHash, utype)
3028
3307
  * .setAccount('0x1234567890123456789012345678901234567890')
3029
- * .decrypt();
3308
+ * .execute();
3030
3309
  * ```
3031
3310
  *
3032
- * @returns The chainable DecryptHandlesBuilder instance.
3311
+ * @returns The chainable DecryptForViewBuilder instance.
3033
3312
  */
3034
3313
  setAccount(account) {
3035
3314
  this.account = account;
@@ -3038,6 +3317,19 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3038
3317
  getAccount() {
3039
3318
  return this.account;
3040
3319
  }
3320
+ withPermit(permitOrPermitHash) {
3321
+ if (typeof permitOrPermitHash === "string") {
3322
+ this.permitHash = permitOrPermitHash;
3323
+ this.permit = void 0;
3324
+ } else if (permitOrPermitHash === void 0) {
3325
+ this.permitHash = void 0;
3326
+ this.permit = void 0;
3327
+ } else {
3328
+ this.permit = permitOrPermitHash;
3329
+ this.permitHash = void 0;
3330
+ }
3331
+ return this;
3332
+ }
3041
3333
  /**
3042
3334
  * @param permitHash - Permit hash to decrypt values from. Used to fetch the correct permit.
3043
3335
  *
@@ -3046,16 +3338,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3046
3338
  *
3047
3339
  * Example:
3048
3340
  * ```typescript
3049
- * const unsealed = await decryptHandle(ctHash, utype)
3341
+ * const unsealed = await client.decryptForView(ctHash, utype)
3050
3342
  * .setPermitHash('0x1234567890123456789012345678901234567890')
3051
- * .decrypt();
3343
+ * .execute();
3052
3344
  * ```
3053
3345
  *
3054
- * @returns The chainable DecryptHandlesBuilder instance.
3346
+ * @returns The chainable DecryptForViewBuilder instance.
3055
3347
  */
3348
+ /** @deprecated Use `withPermit(permitHash)` instead. */
3056
3349
  setPermitHash(permitHash) {
3057
- this.permitHash = permitHash;
3058
- return this;
3350
+ return this.withPermit(permitHash);
3059
3351
  }
3060
3352
  getPermitHash() {
3061
3353
  return this.permitHash;
@@ -3067,16 +3359,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3067
3359
  *
3068
3360
  * Example:
3069
3361
  * ```typescript
3070
- * const unsealed = await decryptHandle(ctHash, utype)
3362
+ * const unsealed = await client.decryptForView(ctHash, utype)
3071
3363
  * .setPermit(permit)
3072
- * .decrypt();
3364
+ * .execute();
3073
3365
  * ```
3074
3366
  *
3075
- * @returns The chainable DecryptHandlesBuilder instance.
3367
+ * @returns The chainable DecryptForViewBuilder instance.
3076
3368
  */
3369
+ /** @deprecated Use `withPermit(permit)` instead. */
3077
3370
  setPermit(permit) {
3078
- this.permit = permit;
3079
- return this;
3371
+ return this.withPermit(permit);
3080
3372
  }
3081
3373
  getPermit() {
3082
3374
  return this.permit;
@@ -3087,7 +3379,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3087
3379
  }
3088
3380
  validateUtypeOrThrow() {
3089
3381
  if (!isValidUtype(this.utype))
3090
- throw new CofhesdkError({
3382
+ throw new CofheError({
3091
3383
  code: "INVALID_UTYPE" /* InvalidUtype */,
3092
3384
  message: `Invalid utype to decrypt to`,
3093
3385
  context: {
@@ -3103,7 +3395,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3103
3395
  if (this.permitHash) {
3104
3396
  const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
3105
3397
  if (!permit2) {
3106
- throw new CofhesdkError({
3398
+ throw new CofheError({
3107
3399
  code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
3108
3400
  message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
3109
3401
  hint: "Ensure the permit exists and is valid.",
@@ -3118,7 +3410,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3118
3410
  }
3119
3411
  const permit = await permits.getActivePermit(this.chainId, this.account);
3120
3412
  if (!permit) {
3121
- throw new CofhesdkError({
3413
+ throw new CofheError({
3122
3414
  code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
3123
3415
  message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
3124
3416
  hint: "Ensure a permit exists for this account on this chain.",
@@ -3135,8 +3427,8 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3135
3427
  */
3136
3428
  async mocksSealOutput(permit) {
3137
3429
  this.assertPublicClient();
3138
- const mocksSealOutputDelay = this.config.mocks.sealOutputDelay;
3139
- return cofheMocksSealOutput(this.ctHash, this.utype, permit, this.publicClient, mocksSealOutputDelay);
3430
+ const mocksDecryptDelay = this.config.mocks.decryptDelay;
3431
+ return cofheMocksDecryptForView(this.ctHash, this.utype, permit, this.publicClient, mocksDecryptDelay);
3140
3432
  }
3141
3433
  /**
3142
3434
  * In the production context, perform a true decryption with the CoFHE coprocessor.
@@ -3161,15 +3453,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3161
3453
  *
3162
3454
  * Example:
3163
3455
  * ```typescript
3164
- * const unsealed = await decryptHandle(ctHash, utype)
3456
+ * const unsealed = await client.decryptForView(ctHash, utype)
3165
3457
  * .setChainId(11155111) // optional
3166
3458
  * .setAccount('0x123...890') // optional
3167
- * .decrypt(); // execute
3459
+ * .withPermit() // optional
3460
+ * .execute(); // execute
3168
3461
  * ```
3169
3462
  *
3170
3463
  * @returns The unsealed item.
3171
3464
  */
3172
- async decrypt() {
3465
+ async execute() {
3173
3466
  this.validateUtypeOrThrow();
3174
3467
  const permit = await this.getResolvedPermit();
3175
3468
  PermitUtils.validate(permit);
@@ -3185,6 +3478,394 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3185
3478
  }
3186
3479
  };
3187
3480
 
3481
+ // core/decrypt/tnDecrypt.ts
3482
+ function normalizeSignature(signature) {
3483
+ if (typeof signature !== "string") {
3484
+ throw new CofheError({
3485
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3486
+ message: "decrypt response missing signature",
3487
+ context: {
3488
+ signature
3489
+ }
3490
+ });
3491
+ }
3492
+ const trimmed = signature.trim();
3493
+ if (trimmed.length === 0) {
3494
+ throw new CofheError({
3495
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3496
+ message: "decrypt response returned empty signature"
3497
+ });
3498
+ }
3499
+ return trimmed.startsWith("0x") ? trimmed.slice(2) : trimmed;
3500
+ }
3501
+ function parseDecryptedBytesToBigInt(decrypted) {
3502
+ if (!Array.isArray(decrypted)) {
3503
+ throw new CofheError({
3504
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3505
+ message: "decrypt response field <decrypted> must be a byte array",
3506
+ context: {
3507
+ decrypted
3508
+ }
3509
+ });
3510
+ }
3511
+ if (decrypted.length === 0) {
3512
+ throw new CofheError({
3513
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3514
+ message: "decrypt response field <decrypted> was an empty byte array",
3515
+ context: {
3516
+ decrypted
3517
+ }
3518
+ });
3519
+ }
3520
+ let hex = "";
3521
+ for (const b of decrypted) {
3522
+ if (typeof b !== "number" || !Number.isInteger(b) || b < 0 || b > 255) {
3523
+ throw new CofheError({
3524
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3525
+ message: "decrypt response field <decrypted> contained a non-byte value",
3526
+ context: {
3527
+ badElement: b,
3528
+ decrypted
3529
+ }
3530
+ });
3531
+ }
3532
+ hex += b.toString(16).padStart(2, "0");
3533
+ }
3534
+ return BigInt(`0x${hex}`);
3535
+ }
3536
+ function assertTnDecryptResponse(value) {
3537
+ if (value == null || typeof value !== "object") {
3538
+ throw new CofheError({
3539
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3540
+ message: "decrypt response must be a JSON object",
3541
+ context: {
3542
+ value
3543
+ }
3544
+ });
3545
+ }
3546
+ const v = value;
3547
+ const decrypted = v.decrypted;
3548
+ const signature = v.signature;
3549
+ const encryptionType = v.encryption_type;
3550
+ const errorMessage = v.error_message;
3551
+ if (!Array.isArray(decrypted)) {
3552
+ throw new CofheError({
3553
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3554
+ message: "decrypt response missing <decrypted> byte array",
3555
+ context: { decryptResponse: value }
3556
+ });
3557
+ }
3558
+ if (typeof signature !== "string") {
3559
+ throw new CofheError({
3560
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3561
+ message: "decrypt response missing <signature> string",
3562
+ context: { decryptResponse: value }
3563
+ });
3564
+ }
3565
+ if (typeof encryptionType !== "number") {
3566
+ throw new CofheError({
3567
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3568
+ message: "decrypt response missing <encryption_type> number",
3569
+ context: { decryptResponse: value }
3570
+ });
3571
+ }
3572
+ if (!(typeof errorMessage === "string" || errorMessage === null)) {
3573
+ throw new CofheError({
3574
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3575
+ message: "decrypt response field <error_message> must be string or null",
3576
+ context: { decryptResponse: value }
3577
+ });
3578
+ }
3579
+ return {
3580
+ decrypted,
3581
+ signature,
3582
+ encryption_type: encryptionType,
3583
+ error_message: errorMessage
3584
+ };
3585
+ }
3586
+ async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
3587
+ const body = {
3588
+ ct_tempkey: ctHash.toString(16).padStart(64, "0"),
3589
+ host_chain_id: chainId
3590
+ };
3591
+ if (permission) {
3592
+ body.permit = permission;
3593
+ }
3594
+ let response;
3595
+ try {
3596
+ response = await fetch(`${thresholdNetworkUrl}/decrypt`, {
3597
+ method: "POST",
3598
+ headers: {
3599
+ "Content-Type": "application/json"
3600
+ },
3601
+ body: JSON.stringify(body)
3602
+ });
3603
+ } catch (e) {
3604
+ throw new CofheError({
3605
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3606
+ message: `decrypt request failed`,
3607
+ hint: "Ensure the threshold network URL is valid and reachable.",
3608
+ cause: e instanceof Error ? e : void 0,
3609
+ context: {
3610
+ thresholdNetworkUrl,
3611
+ body
3612
+ }
3613
+ });
3614
+ }
3615
+ const responseText = await response.text();
3616
+ if (!response.ok) {
3617
+ let errorMessage = response.statusText || `HTTP ${response.status}`;
3618
+ try {
3619
+ const errorBody = JSON.parse(responseText);
3620
+ const maybeMessage = errorBody.error_message || errorBody.message;
3621
+ if (typeof maybeMessage === "string" && maybeMessage.length > 0)
3622
+ errorMessage = maybeMessage;
3623
+ } catch {
3624
+ const trimmed = responseText.trim();
3625
+ if (trimmed.length > 0)
3626
+ errorMessage = trimmed;
3627
+ }
3628
+ throw new CofheError({
3629
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3630
+ message: `decrypt request failed: ${errorMessage}`,
3631
+ hint: "Check the threshold network URL and request parameters.",
3632
+ context: {
3633
+ thresholdNetworkUrl,
3634
+ status: response.status,
3635
+ statusText: response.statusText,
3636
+ body,
3637
+ responseText
3638
+ }
3639
+ });
3640
+ }
3641
+ let rawJson;
3642
+ try {
3643
+ rawJson = JSON.parse(responseText);
3644
+ } catch (e) {
3645
+ throw new CofheError({
3646
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3647
+ message: `Failed to parse decrypt response`,
3648
+ cause: e instanceof Error ? e : void 0,
3649
+ context: {
3650
+ thresholdNetworkUrl,
3651
+ body,
3652
+ responseText
3653
+ }
3654
+ });
3655
+ }
3656
+ const decryptResponse = assertTnDecryptResponse(rawJson);
3657
+ if (decryptResponse.error_message) {
3658
+ throw new CofheError({
3659
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3660
+ message: `decrypt request failed: ${decryptResponse.error_message}`,
3661
+ context: {
3662
+ thresholdNetworkUrl,
3663
+ body,
3664
+ decryptResponse
3665
+ }
3666
+ });
3667
+ }
3668
+ const decryptedValue = parseDecryptedBytesToBigInt(decryptResponse.decrypted);
3669
+ const signature = normalizeSignature(decryptResponse.signature);
3670
+ return { decryptedValue, signature };
3671
+ }
3672
+
3673
+ // core/decrypt/decryptForTxBuilder.ts
3674
+ var DecryptForTxBuilder = class extends BaseBuilder {
3675
+ ctHash;
3676
+ permitHash;
3677
+ permit;
3678
+ permitSelection = "unset";
3679
+ constructor(params) {
3680
+ super({
3681
+ config: params.config,
3682
+ publicClient: params.publicClient,
3683
+ walletClient: params.walletClient,
3684
+ chainId: params.chainId,
3685
+ account: params.account,
3686
+ requireConnected: params.requireConnected
3687
+ });
3688
+ this.ctHash = params.ctHash;
3689
+ }
3690
+ setChainId(chainId) {
3691
+ this.chainId = chainId;
3692
+ return this;
3693
+ }
3694
+ getChainId() {
3695
+ return this.chainId;
3696
+ }
3697
+ setAccount(account) {
3698
+ this.account = account;
3699
+ return this;
3700
+ }
3701
+ getAccount() {
3702
+ return this.account;
3703
+ }
3704
+ withPermit(permitOrPermitHash) {
3705
+ if (this.permitSelection === "with-permit") {
3706
+ throw new CofheError({
3707
+ code: "INTERNAL_ERROR" /* InternalError */,
3708
+ message: "decryptForTx: withPermit() can only be selected once.",
3709
+ hint: "Choose the permit mode once. If you need a different permit, start a new decryptForTx() builder chain."
3710
+ });
3711
+ }
3712
+ if (this.permitSelection === "without-permit") {
3713
+ throw new CofheError({
3714
+ code: "INTERNAL_ERROR" /* InternalError */,
3715
+ message: "decryptForTx: cannot call withPermit() after withoutPermit() has been selected.",
3716
+ hint: "Choose exactly one permit mode: either call .withPermit(...) or .withoutPermit(), but not both."
3717
+ });
3718
+ }
3719
+ this.permitSelection = "with-permit";
3720
+ if (typeof permitOrPermitHash === "string") {
3721
+ this.permitHash = permitOrPermitHash;
3722
+ this.permit = void 0;
3723
+ } else if (permitOrPermitHash === void 0) {
3724
+ this.permitHash = void 0;
3725
+ this.permit = void 0;
3726
+ } else {
3727
+ this.permit = permitOrPermitHash;
3728
+ this.permitHash = void 0;
3729
+ }
3730
+ return this;
3731
+ }
3732
+ /**
3733
+ * Select "no permit" mode.
3734
+ *
3735
+ * This uses global allowance (no permit required) and sends an empty permission payload to `/decrypt`.
3736
+ */
3737
+ withoutPermit() {
3738
+ if (this.permitSelection === "without-permit") {
3739
+ throw new CofheError({
3740
+ code: "INTERNAL_ERROR" /* InternalError */,
3741
+ message: "decryptForTx: withoutPermit() can only be selected once.",
3742
+ hint: "Choose the permit mode once. If you need a different mode, start a new decryptForTx() builder chain."
3743
+ });
3744
+ }
3745
+ if (this.permitSelection === "with-permit") {
3746
+ throw new CofheError({
3747
+ code: "INTERNAL_ERROR" /* InternalError */,
3748
+ message: "decryptForTx: cannot call withoutPermit() after withPermit() has been selected.",
3749
+ hint: "Choose exactly one permit mode: either call .withPermit(...) or .withoutPermit(), but not both."
3750
+ });
3751
+ }
3752
+ this.permitSelection = "without-permit";
3753
+ this.permitHash = void 0;
3754
+ this.permit = void 0;
3755
+ return this;
3756
+ }
3757
+ getPermit() {
3758
+ return this.permit;
3759
+ }
3760
+ getPermitHash() {
3761
+ return this.permitHash;
3762
+ }
3763
+ async getThresholdNetworkUrl() {
3764
+ this.assertChainId();
3765
+ return getThresholdNetworkUrlOrThrow(this.config, this.chainId);
3766
+ }
3767
+ async getResolvedPermit() {
3768
+ if (this.permitSelection === "unset") {
3769
+ throw new CofheError({
3770
+ code: "INTERNAL_ERROR" /* InternalError */,
3771
+ message: "decryptForTx: missing permit selection; call withPermit(...) or withoutPermit() before execute().",
3772
+ hint: "Call .withPermit() to use the active permit, or .withoutPermit() for global allowance."
3773
+ });
3774
+ }
3775
+ if (this.permitSelection === "without-permit") {
3776
+ return null;
3777
+ }
3778
+ if (this.permit)
3779
+ return this.permit;
3780
+ this.assertChainId();
3781
+ this.assertAccount();
3782
+ if (this.permitHash) {
3783
+ const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
3784
+ if (!permit2) {
3785
+ throw new CofheError({
3786
+ code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
3787
+ message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
3788
+ hint: "Ensure the permit exists and is valid.",
3789
+ context: {
3790
+ chainId: this.chainId,
3791
+ account: this.account,
3792
+ permitHash: this.permitHash
3793
+ }
3794
+ });
3795
+ }
3796
+ return permit2;
3797
+ }
3798
+ const permit = await permits.getActivePermit(this.chainId, this.account);
3799
+ if (!permit) {
3800
+ throw new CofheError({
3801
+ code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
3802
+ message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
3803
+ hint: "Create a permit (e.g. client.permits.createSelf(...)) and/or set it active (client.permits.selectActivePermit(hash)).",
3804
+ context: {
3805
+ chainId: this.chainId,
3806
+ account: this.account
3807
+ }
3808
+ });
3809
+ }
3810
+ return permit;
3811
+ }
3812
+ /**
3813
+ * On hardhat, interact with MockThresholdNetwork contract
3814
+ */
3815
+ async mocksDecryptForTx(permit) {
3816
+ this.assertPublicClient();
3817
+ const delay = this.config.mocks.decryptDelay;
3818
+ const result = await cofheMocksDecryptForTx(this.ctHash, 0, permit, this.publicClient, delay);
3819
+ return result;
3820
+ }
3821
+ /**
3822
+ * In the production context, perform a true decryption with the CoFHE coprocessor.
3823
+ */
3824
+ async productionDecryptForTx(permit) {
3825
+ this.assertChainId();
3826
+ this.assertPublicClient();
3827
+ const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
3828
+ const permission = permit ? PermitUtils.getPermission(permit, true) : null;
3829
+ const { decryptedValue, signature } = await tnDecrypt(this.ctHash, this.chainId, permission, thresholdNetworkUrl);
3830
+ return {
3831
+ ctHash: this.ctHash,
3832
+ decryptedValue,
3833
+ signature
3834
+ };
3835
+ }
3836
+ /**
3837
+ * Final step of the decryptForTx process. MUST BE CALLED LAST IN THE CHAIN.
3838
+ *
3839
+ * You must explicitly choose one permit mode before calling `execute()`:
3840
+ * - `withPermit(permit)` / `withPermit(permitHash)` / `withPermit()` (active permit)
3841
+ * - `withoutPermit()` (global allowance)
3842
+ */
3843
+ async execute() {
3844
+ const permit = await this.getResolvedPermit();
3845
+ if (permit !== null) {
3846
+ PermitUtils.validate(permit);
3847
+ PermitUtils.isValid(permit);
3848
+ const chainId = permit._signedDomain.chainId;
3849
+ if (chainId === hardhat2.id) {
3850
+ return await this.mocksDecryptForTx(permit);
3851
+ } else {
3852
+ return await this.productionDecryptForTx(permit);
3853
+ }
3854
+ } else {
3855
+ if (!this.chainId) {
3856
+ this.assertPublicClient();
3857
+ this.chainId = await getPublicClientChainID(this.publicClient);
3858
+ }
3859
+ this.assertChainId();
3860
+ if (this.chainId === hardhat2.id) {
3861
+ return await this.mocksDecryptForTx(null);
3862
+ } else {
3863
+ return await this.productionDecryptForTx(null);
3864
+ }
3865
+ }
3866
+ }
3867
+ };
3868
+
3188
3869
  // core/client.ts
3189
3870
  var InitialConnectStore = {
3190
3871
  connected: false,
@@ -3195,9 +3876,10 @@ var InitialConnectStore = {
3195
3876
  publicClient: void 0,
3196
3877
  walletClient: void 0
3197
3878
  };
3198
- function createCofhesdkClientBase(opts) {
3879
+ function createCofheClientBase(opts) {
3199
3880
  const keysStorage = createKeysStore(opts.config.fheKeyStorage);
3200
3881
  const connectStore = vanilla.createStore(() => InitialConnectStore);
3882
+ let connectAttemptId = 0;
3201
3883
  const updateConnectState = (partial) => {
3202
3884
  connectStore.setState((state) => ({ ...state, ...partial }));
3203
3885
  };
@@ -3205,7 +3887,7 @@ function createCofhesdkClientBase(opts) {
3205
3887
  const state = connectStore.getState();
3206
3888
  const notConnected = !state.connected || !state.account || !state.chainId || !state.publicClient || !state.walletClient;
3207
3889
  if (notConnected) {
3208
- throw new CofhesdkError({
3890
+ throw new CofheError({
3209
3891
  code: "NOT_CONNECTED" /* NotConnected */,
3210
3892
  message: "Client must be connected, account and chainId must be initialized",
3211
3893
  hint: "Ensure client.connect() has been called and awaited.",
@@ -3223,6 +3905,8 @@ function createCofhesdkClientBase(opts) {
3223
3905
  const state = connectStore.getState();
3224
3906
  if (state.connected && state.publicClient === publicClient && state.walletClient === walletClient)
3225
3907
  return;
3908
+ connectAttemptId += 1;
3909
+ const localAttemptId = connectAttemptId;
3226
3910
  updateConnectState({
3227
3911
  ...InitialConnectStore,
3228
3912
  connecting: true
@@ -3230,6 +3914,8 @@ function createCofhesdkClientBase(opts) {
3230
3914
  try {
3231
3915
  const chainId = await getPublicClientChainID(publicClient);
3232
3916
  const account = await getWalletClientAccount(walletClient);
3917
+ if (localAttemptId !== connectAttemptId)
3918
+ return;
3233
3919
  updateConnectState({
3234
3920
  connected: true,
3235
3921
  connecting: false,
@@ -3240,6 +3926,8 @@ function createCofhesdkClientBase(opts) {
3240
3926
  walletClient
3241
3927
  });
3242
3928
  } catch (e) {
3929
+ if (localAttemptId !== connectAttemptId)
3930
+ return;
3243
3931
  updateConnectState({
3244
3932
  ...InitialConnectStore,
3245
3933
  connectError: e
@@ -3247,6 +3935,10 @@ function createCofhesdkClientBase(opts) {
3247
3935
  throw e;
3248
3936
  }
3249
3937
  }
3938
+ function disconnect() {
3939
+ connectAttemptId += 1;
3940
+ updateConnectState({ ...InitialConnectStore });
3941
+ }
3250
3942
  function encryptInputs(inputs) {
3251
3943
  const state = connectStore.getState();
3252
3944
  return new EncryptInputsBuilder({
@@ -3266,16 +3958,28 @@ function createCofhesdkClientBase(opts) {
3266
3958
  requireConnected: _requireConnected
3267
3959
  });
3268
3960
  }
3269
- function decryptHandle(ctHash, utype) {
3961
+ function decryptForView(ctHash, utype) {
3270
3962
  const state = connectStore.getState();
3271
- return new DecryptHandlesBuilder({
3963
+ return new DecryptForViewBuilder({
3272
3964
  ctHash,
3273
3965
  utype,
3274
- chainId: state.chainId ?? void 0,
3275
- account: state.account ?? void 0,
3966
+ chainId: state.chainId,
3967
+ account: state.account,
3276
3968
  config: opts.config,
3277
- publicClient: state.publicClient ?? void 0,
3278
- walletClient: state.walletClient ?? void 0,
3969
+ publicClient: state.publicClient,
3970
+ walletClient: state.walletClient,
3971
+ requireConnected: _requireConnected
3972
+ });
3973
+ }
3974
+ function decryptForTx(ctHash) {
3975
+ const state = connectStore.getState();
3976
+ return new DecryptForTxBuilder({
3977
+ ctHash,
3978
+ chainId: state.chainId,
3979
+ account: state.account,
3980
+ config: opts.config,
3981
+ publicClient: state.publicClient,
3982
+ walletClient: state.walletClient,
3279
3983
  requireConnected: _requireConnected
3280
3984
  });
3281
3985
  }
@@ -3284,7 +3988,7 @@ function createCofhesdkClientBase(opts) {
3284
3988
  const _chainId = chainId ?? state.chainId;
3285
3989
  const _account = account ?? state.account;
3286
3990
  if (_chainId == null || _account == null) {
3287
- throw new CofhesdkError({
3991
+ throw new CofheError({
3288
3992
  code: "NOT_CONNECTED" /* NotConnected */,
3289
3993
  message: "ChainId or account not available.",
3290
3994
  hint: "Ensure client.connect() has been called, or provide chainId and account explicitly.",
@@ -3351,9 +4055,9 @@ function createCofhesdkClientBase(opts) {
3351
4055
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
3352
4056
  return permits.selectActivePermit(_chainId, _account, hash);
3353
4057
  },
3354
- removePermit: async (hash, chainId, account, force) => {
4058
+ removePermit: async (hash, chainId, account) => {
3355
4059
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
3356
- return permits.removePermit(_chainId, _account, hash, force);
4060
+ return permits.removePermit(_chainId, _account, hash);
3357
4061
  },
3358
4062
  removeActivePermit: async (chainId, account) => {
3359
4063
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
@@ -3369,6 +4073,9 @@ function createCofhesdkClientBase(opts) {
3369
4073
  getSnapshot: connectStore.getState,
3370
4074
  subscribe: connectStore.subscribe,
3371
4075
  // flags (read-only: reflect snapshot)
4076
+ get connection() {
4077
+ return connectStore.getState();
4078
+ },
3372
4079
  get connected() {
3373
4080
  return connectStore.getState().connected;
3374
4081
  },
@@ -3378,8 +4085,14 @@ function createCofhesdkClientBase(opts) {
3378
4085
  // config & platform-specific (read-only)
3379
4086
  config: opts.config,
3380
4087
  connect,
4088
+ disconnect,
3381
4089
  encryptInputs,
3382
- decryptHandle,
4090
+ decryptForView,
4091
+ /**
4092
+ * @deprecated Use `decryptForView` instead. Kept for backward compatibility.
4093
+ */
4094
+ decryptHandle: decryptForView,
4095
+ decryptForTx,
3383
4096
  permits: clientPermits
3384
4097
  // Add SDK-specific methods below that require connection
3385
4098
  // Example:
@@ -3391,24 +4104,31 @@ function createCofhesdkClientBase(opts) {
3391
4104
  }
3392
4105
 
3393
4106
  exports.CONNECT_STORE_DEFAULTS = InitialConnectStore;
3394
- exports.CofhesdkError = CofhesdkError;
3395
- exports.CofhesdkErrorCode = CofhesdkErrorCode;
3396
- exports.DecryptHandlesBuilder = DecryptHandlesBuilder;
4107
+ exports.CofheError = CofheError;
4108
+ exports.CofheErrorCode = CofheErrorCode;
4109
+ exports.DecryptForTxBuilder = DecryptForTxBuilder;
4110
+ exports.DecryptForViewBuilder = DecryptForViewBuilder;
3397
4111
  exports.EncryptInputsBuilder = EncryptInputsBuilder;
3398
4112
  exports.EncryptStep = EncryptStep;
3399
4113
  exports.Encryptable = Encryptable;
3400
4114
  exports.FheAllUTypes = FheAllUTypes;
3401
4115
  exports.FheTypes = FheTypes;
3402
4116
  exports.FheUintUTypes = FheUintUTypes;
4117
+ exports.MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY = MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY;
4118
+ exports.MOCKS_THRESHOLD_NETWORK_ADDRESS = MOCKS_THRESHOLD_NETWORK_ADDRESS;
4119
+ exports.MOCKS_ZK_VERIFIER_ADDRESS = MOCKS_ZK_VERIFIER_ADDRESS;
3403
4120
  exports.MOCKS_ZK_VERIFIER_SIGNER_ADDRESS = MOCKS_ZK_VERIFIER_SIGNER_ADDRESS;
4121
+ exports.MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY;
4122
+ exports.TASK_MANAGER_ADDRESS = TASK_MANAGER_ADDRESS;
4123
+ exports.TEST_BED_ADDRESS = TEST_BED_ADDRESS;
3404
4124
  exports.assertCorrectEncryptedItemInput = assertCorrectEncryptedItemInput;
3405
- exports.createCofhesdkClientBase = createCofhesdkClientBase;
3406
- exports.createCofhesdkConfigBase = createCofhesdkConfigBase;
4125
+ exports.createCofheClientBase = createCofheClientBase;
4126
+ exports.createCofheConfigBase = createCofheConfigBase;
3407
4127
  exports.createKeysStore = createKeysStore;
3408
4128
  exports.fetchKeys = fetchKeys;
3409
4129
  exports.fheTypeToString = fheTypeToString;
3410
- exports.getCofhesdkConfigItem = getCofhesdkConfigItem;
3411
- exports.isCofhesdkError = isCofhesdkError;
4130
+ exports.getCofheConfigItem = getCofheConfigItem;
4131
+ exports.isCofheError = isCofheError;
3412
4132
  exports.isEncryptableItem = isEncryptableItem;
3413
4133
  exports.isLastEncryptionStep = isLastEncryptionStep;
3414
4134
  exports.zkProveWithWorker = zkProveWithWorker;