@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
@@ -1,61 +1,61 @@
1
- import { hardhat as hardhat$1 } from './chunk-WEAZ25JO.js';
2
- import { permitStore, PermitUtils } from './chunk-UGBVZNRT.js';
1
+ import { hardhat as hardhat$1 } from './chunk-TBLR7NNE.js';
2
+ import { permitStore, PermitUtils, MOCKS_THRESHOLD_NETWORK_ADDRESS, MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY, MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY, MOCKS_ZK_VERIFIER_ADDRESS } from './chunk-NWDKXBIP.js';
3
3
  import { createStore } from 'zustand/vanilla';
4
- import { createWalletClient, http, encodePacked, keccak256, toBytes, hashMessage, getAddress } from 'viem';
4
+ import { pad, toHex, encodePacked, keccak256, createWalletClient, http, toBytes, hashMessage, getAddress } from 'viem';
5
5
  import { hardhat } from 'viem/chains';
6
- import { privateKeyToAccount } from 'viem/accounts';
6
+ import { sign, privateKeyToAccount } from 'viem/accounts';
7
7
  import { z } from 'zod';
8
8
  import { persist, createJSONStorage } from 'zustand/middleware';
9
9
  import { produce } from 'immer';
10
10
 
11
11
  // core/error.ts
12
- var CofhesdkErrorCode = /* @__PURE__ */ ((CofhesdkErrorCode2) => {
13
- CofhesdkErrorCode2["InternalError"] = "INTERNAL_ERROR";
14
- CofhesdkErrorCode2["UnknownEnvironment"] = "UNKNOWN_ENVIRONMENT";
15
- CofhesdkErrorCode2["InitTfheFailed"] = "INIT_TFHE_FAILED";
16
- CofhesdkErrorCode2["InitViemFailed"] = "INIT_VIEM_FAILED";
17
- CofhesdkErrorCode2["InitEthersFailed"] = "INIT_ETHERS_FAILED";
18
- CofhesdkErrorCode2["NotConnected"] = "NOT_CONNECTED";
19
- CofhesdkErrorCode2["MissingPublicClient"] = "MISSING_PUBLIC_CLIENT";
20
- CofhesdkErrorCode2["MissingWalletClient"] = "MISSING_WALLET_CLIENT";
21
- CofhesdkErrorCode2["MissingProviderParam"] = "MISSING_PROVIDER_PARAM";
22
- CofhesdkErrorCode2["EmptySecurityZonesParam"] = "EMPTY_SECURITY_ZONES_PARAM";
23
- CofhesdkErrorCode2["InvalidPermitData"] = "INVALID_PERMIT_DATA";
24
- CofhesdkErrorCode2["InvalidPermitDomain"] = "INVALID_PERMIT_DOMAIN";
25
- CofhesdkErrorCode2["PermitNotFound"] = "PERMIT_NOT_FOUND";
26
- CofhesdkErrorCode2["CannotRemoveLastPermit"] = "CANNOT_REMOVE_LAST_PERMIT";
27
- CofhesdkErrorCode2["AccountUninitialized"] = "ACCOUNT_UNINITIALIZED";
28
- CofhesdkErrorCode2["ChainIdUninitialized"] = "CHAIN_ID_UNINITIALIZED";
29
- CofhesdkErrorCode2["SealOutputFailed"] = "SEAL_OUTPUT_FAILED";
30
- CofhesdkErrorCode2["SealOutputReturnedNull"] = "SEAL_OUTPUT_RETURNED_NULL";
31
- CofhesdkErrorCode2["InvalidUtype"] = "INVALID_UTYPE";
32
- CofhesdkErrorCode2["DecryptFailed"] = "DECRYPT_FAILED";
33
- CofhesdkErrorCode2["DecryptReturnedNull"] = "DECRYPT_RETURNED_NULL";
34
- CofhesdkErrorCode2["ZkMocksInsertCtHashesFailed"] = "ZK_MOCKS_INSERT_CT_HASHES_FAILED";
35
- CofhesdkErrorCode2["ZkMocksCalcCtHashesFailed"] = "ZK_MOCKS_CALC_CT_HASHES_FAILED";
36
- CofhesdkErrorCode2["ZkMocksVerifySignFailed"] = "ZK_MOCKS_VERIFY_SIGN_FAILED";
37
- CofhesdkErrorCode2["ZkMocksCreateProofSignatureFailed"] = "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED";
38
- CofhesdkErrorCode2["ZkVerifyFailed"] = "ZK_VERIFY_FAILED";
39
- CofhesdkErrorCode2["ZkPackFailed"] = "ZK_PACK_FAILED";
40
- CofhesdkErrorCode2["ZkProveFailed"] = "ZK_PROVE_FAILED";
41
- CofhesdkErrorCode2["EncryptRemainingInItems"] = "ENCRYPT_REMAINING_IN_ITEMS";
42
- CofhesdkErrorCode2["ZkUninitialized"] = "ZK_UNINITIALIZED";
43
- CofhesdkErrorCode2["ZkVerifierUrlUninitialized"] = "ZK_VERIFIER_URL_UNINITIALIZED";
44
- CofhesdkErrorCode2["ThresholdNetworkUrlUninitialized"] = "THRESHOLD_NETWORK_URL_UNINITIALIZED";
45
- CofhesdkErrorCode2["MissingConfig"] = "MISSING_CONFIG";
46
- CofhesdkErrorCode2["UnsupportedChain"] = "UNSUPPORTED_CHAIN";
47
- CofhesdkErrorCode2["MissingZkBuilderAndCrsGenerator"] = "MISSING_ZK_BUILDER_AND_CRS_GENERATOR";
48
- CofhesdkErrorCode2["MissingTfhePublicKeyDeserializer"] = "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER";
49
- CofhesdkErrorCode2["MissingCompactPkeCrsDeserializer"] = "MISSING_COMPACT_PKE_CRS_DESERIALIZER";
50
- CofhesdkErrorCode2["MissingFheKey"] = "MISSING_FHE_KEY";
51
- CofhesdkErrorCode2["MissingCrs"] = "MISSING_CRS";
52
- CofhesdkErrorCode2["FetchKeysFailed"] = "FETCH_KEYS_FAILED";
53
- CofhesdkErrorCode2["PublicWalletGetChainIdFailed"] = "PUBLIC_WALLET_GET_CHAIN_ID_FAILED";
54
- CofhesdkErrorCode2["PublicWalletGetAddressesFailed"] = "PUBLIC_WALLET_GET_ADDRESSES_FAILED";
55
- CofhesdkErrorCode2["RehydrateKeysStoreFailed"] = "REHYDRATE_KEYS_STORE_FAILED";
56
- return CofhesdkErrorCode2;
57
- })(CofhesdkErrorCode || {});
58
- var CofhesdkError = class _CofhesdkError extends Error {
12
+ var CofheErrorCode = /* @__PURE__ */ ((CofheErrorCode2) => {
13
+ CofheErrorCode2["InternalError"] = "INTERNAL_ERROR";
14
+ CofheErrorCode2["UnknownEnvironment"] = "UNKNOWN_ENVIRONMENT";
15
+ CofheErrorCode2["InitTfheFailed"] = "INIT_TFHE_FAILED";
16
+ CofheErrorCode2["InitViemFailed"] = "INIT_VIEM_FAILED";
17
+ CofheErrorCode2["InitEthersFailed"] = "INIT_ETHERS_FAILED";
18
+ CofheErrorCode2["NotConnected"] = "NOT_CONNECTED";
19
+ CofheErrorCode2["MissingPublicClient"] = "MISSING_PUBLIC_CLIENT";
20
+ CofheErrorCode2["MissingWalletClient"] = "MISSING_WALLET_CLIENT";
21
+ CofheErrorCode2["MissingProviderParam"] = "MISSING_PROVIDER_PARAM";
22
+ CofheErrorCode2["EmptySecurityZonesParam"] = "EMPTY_SECURITY_ZONES_PARAM";
23
+ CofheErrorCode2["InvalidPermitData"] = "INVALID_PERMIT_DATA";
24
+ CofheErrorCode2["InvalidPermitDomain"] = "INVALID_PERMIT_DOMAIN";
25
+ CofheErrorCode2["PermitNotFound"] = "PERMIT_NOT_FOUND";
26
+ CofheErrorCode2["CannotRemoveLastPermit"] = "CANNOT_REMOVE_LAST_PERMIT";
27
+ CofheErrorCode2["AccountUninitialized"] = "ACCOUNT_UNINITIALIZED";
28
+ CofheErrorCode2["ChainIdUninitialized"] = "CHAIN_ID_UNINITIALIZED";
29
+ CofheErrorCode2["SealOutputFailed"] = "SEAL_OUTPUT_FAILED";
30
+ CofheErrorCode2["SealOutputReturnedNull"] = "SEAL_OUTPUT_RETURNED_NULL";
31
+ CofheErrorCode2["InvalidUtype"] = "INVALID_UTYPE";
32
+ CofheErrorCode2["DecryptFailed"] = "DECRYPT_FAILED";
33
+ CofheErrorCode2["DecryptReturnedNull"] = "DECRYPT_RETURNED_NULL";
34
+ CofheErrorCode2["ZkMocksInsertCtHashesFailed"] = "ZK_MOCKS_INSERT_CT_HASHES_FAILED";
35
+ CofheErrorCode2["ZkMocksCalcCtHashesFailed"] = "ZK_MOCKS_CALC_CT_HASHES_FAILED";
36
+ CofheErrorCode2["ZkMocksVerifySignFailed"] = "ZK_MOCKS_VERIFY_SIGN_FAILED";
37
+ CofheErrorCode2["ZkMocksCreateProofSignatureFailed"] = "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED";
38
+ CofheErrorCode2["ZkVerifyFailed"] = "ZK_VERIFY_FAILED";
39
+ CofheErrorCode2["ZkPackFailed"] = "ZK_PACK_FAILED";
40
+ CofheErrorCode2["ZkProveFailed"] = "ZK_PROVE_FAILED";
41
+ CofheErrorCode2["EncryptRemainingInItems"] = "ENCRYPT_REMAINING_IN_ITEMS";
42
+ CofheErrorCode2["ZkUninitialized"] = "ZK_UNINITIALIZED";
43
+ CofheErrorCode2["ZkVerifierUrlUninitialized"] = "ZK_VERIFIER_URL_UNINITIALIZED";
44
+ CofheErrorCode2["ThresholdNetworkUrlUninitialized"] = "THRESHOLD_NETWORK_URL_UNINITIALIZED";
45
+ CofheErrorCode2["MissingConfig"] = "MISSING_CONFIG";
46
+ CofheErrorCode2["UnsupportedChain"] = "UNSUPPORTED_CHAIN";
47
+ CofheErrorCode2["MissingZkBuilderAndCrsGenerator"] = "MISSING_ZK_BUILDER_AND_CRS_GENERATOR";
48
+ CofheErrorCode2["MissingTfhePublicKeyDeserializer"] = "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER";
49
+ CofheErrorCode2["MissingCompactPkeCrsDeserializer"] = "MISSING_COMPACT_PKE_CRS_DESERIALIZER";
50
+ CofheErrorCode2["MissingFheKey"] = "MISSING_FHE_KEY";
51
+ CofheErrorCode2["MissingCrs"] = "MISSING_CRS";
52
+ CofheErrorCode2["FetchKeysFailed"] = "FETCH_KEYS_FAILED";
53
+ CofheErrorCode2["PublicWalletGetChainIdFailed"] = "PUBLIC_WALLET_GET_CHAIN_ID_FAILED";
54
+ CofheErrorCode2["PublicWalletGetAddressesFailed"] = "PUBLIC_WALLET_GET_ADDRESSES_FAILED";
55
+ CofheErrorCode2["RehydrateKeysStoreFailed"] = "REHYDRATE_KEYS_STORE_FAILED";
56
+ return CofheErrorCode2;
57
+ })(CofheErrorCode || {});
58
+ var CofheError = class _CofheError extends Error {
59
59
  code;
60
60
  cause;
61
61
  hint;
@@ -63,25 +63,25 @@ var CofhesdkError = class _CofhesdkError extends Error {
63
63
  constructor({ code, message, cause, hint, context }) {
64
64
  const fullMessage = cause ? `${message} | Caused by: ${cause.message}` : message;
65
65
  super(fullMessage);
66
- this.name = "CofhesdkError";
66
+ this.name = "CofheError";
67
67
  this.code = code;
68
68
  this.cause = cause;
69
69
  this.hint = hint;
70
70
  this.context = context;
71
71
  if (Error.captureStackTrace) {
72
- Error.captureStackTrace(this, _CofhesdkError);
72
+ Error.captureStackTrace(this, _CofheError);
73
73
  }
74
74
  }
75
75
  /**
76
- * Creates a CofhesdkError from an unknown error
77
- * If the error is a CofhesdkError, it is returned unchanged, else a new CofhesdkError is created
78
- * If a wrapperError is provided, it is used to create the new CofhesdkError, else a default is used
76
+ * Creates a CofheError from an unknown error
77
+ * If the error is a CofheError, it is returned unchanged, else a new CofheError is created
78
+ * If a wrapperError is provided, it is used to create the new CofheError, else a default is used
79
79
  */
80
80
  static fromError(error, wrapperError) {
81
- if (isCofhesdkError(error))
81
+ if (isCofheError(error))
82
82
  return error;
83
83
  const cause = error instanceof Error ? error : new Error(`${error}`);
84
- return new _CofhesdkError({
84
+ return new _CofheError({
85
85
  code: wrapperError?.code ?? "INTERNAL_ERROR" /* InternalError */,
86
86
  message: wrapperError?.message ?? "An internal error occurred",
87
87
  hint: wrapperError?.hint,
@@ -141,7 +141,7 @@ var bigintSafeJsonStringify = (value) => {
141
141
  return value2;
142
142
  });
143
143
  };
144
- var isCofhesdkError = (error) => error instanceof CofhesdkError;
144
+ var isCofheError = (error) => error instanceof CofheError;
145
145
 
146
146
  // core/types.ts
147
147
  var FheTypes = /* @__PURE__ */ ((FheTypes2) => {
@@ -292,14 +292,14 @@ async function getPublicClientChainID(publicClient) {
292
292
  try {
293
293
  chainId = publicClient.chain?.id ?? await publicClient.getChainId();
294
294
  } catch (e) {
295
- throw new CofhesdkError({
295
+ throw new CofheError({
296
296
  code: "PUBLIC_WALLET_GET_CHAIN_ID_FAILED" /* PublicWalletGetChainIdFailed */,
297
297
  message: "getting chain ID from public client failed",
298
298
  cause: e instanceof Error ? e : void 0
299
299
  });
300
300
  }
301
301
  if (chainId === null) {
302
- throw new CofhesdkError({
302
+ throw new CofheError({
303
303
  code: "PUBLIC_WALLET_GET_CHAIN_ID_FAILED" /* PublicWalletGetChainIdFailed */,
304
304
  message: "chain ID from public client is null"
305
305
  });
@@ -314,14 +314,14 @@ async function getWalletClientAccount(walletClient) {
314
314
  address = (await walletClient.getAddresses())?.[0];
315
315
  }
316
316
  } catch (e) {
317
- throw new CofhesdkError({
317
+ throw new CofheError({
318
318
  code: "PUBLIC_WALLET_GET_ADDRESSES_FAILED" /* PublicWalletGetAddressesFailed */,
319
319
  message: "getting address from wallet client failed",
320
320
  cause: e instanceof Error ? e : void 0
321
321
  });
322
322
  }
323
323
  if (!address) {
324
- throw new CofhesdkError({
324
+ throw new CofheError({
325
325
  code: "PUBLIC_WALLET_GET_ADDRESSES_FAILED" /* PublicWalletGetAddressesFailed */,
326
326
  message: "address from wallet client is null"
327
327
  });
@@ -425,7 +425,7 @@ var zkPack = (items, builder) => {
425
425
  break;
426
426
  }
427
427
  default: {
428
- throw new CofhesdkError({
428
+ throw new CofheError({
429
429
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
430
430
  message: `Invalid utype: ${item.utype}`,
431
431
  hint: `Ensure that the utype is valid, using the Encryptable type, for example: Encryptable.uint128(100n)`,
@@ -437,7 +437,7 @@ var zkPack = (items, builder) => {
437
437
  }
438
438
  }
439
439
  if (totalBits > MAX_ENCRYPTABLE_BITS) {
440
- throw new CofhesdkError({
440
+ throw new CofheError({
441
441
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
442
442
  message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
443
443
  hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
@@ -501,14 +501,14 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
501
501
  });
502
502
  if (!response.ok) {
503
503
  const errorBody = await response.text();
504
- throw new CofhesdkError({
504
+ throw new CofheError({
505
505
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
506
506
  message: `HTTP error! ZK proof verification failed - ${errorBody}`
507
507
  });
508
508
  }
509
509
  const json = await response.json();
510
510
  if (json.status !== "success") {
511
- throw new CofhesdkError({
511
+ throw new CofheError({
512
512
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
513
513
  message: `ZK proof verification response malformed - ${json.error}`
514
514
  });
@@ -520,7 +520,7 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
520
520
  };
521
521
  });
522
522
  } catch (e) {
523
- throw new CofhesdkError({
523
+ throw new CofheError({
524
524
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
525
525
  message: `ZK proof verification failed`,
526
526
  cause: e instanceof Error ? e : void 0
@@ -638,9 +638,6 @@ var MockZkVerifierAbi = [
638
638
  },
639
639
  { type: "error", name: "InvalidInputs", inputs: [] }
640
640
  ];
641
- var MocksZkVerifierAddress = "0x0000000000000000000000000000000000000100";
642
- var MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = "0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512";
643
- var MOCKS_ZK_VERIFIER_SIGNER_ADDRESS = "0x6E12D8C87503D4287c294f2Fdef96ACd9DFf6bd2";
644
641
  function createMockZkVerifierSigner() {
645
642
  return createWalletClient({
646
643
  chain: hardhat,
@@ -683,7 +680,7 @@ async function cofheMocksCheckEncryptableBits(items) {
683
680
  }
684
681
  }
685
682
  if (totalBits > MAX_ENCRYPTABLE_BITS) {
686
- throw new CofhesdkError({
683
+ throw new CofheError({
687
684
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
688
685
  message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
689
686
  hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
@@ -706,18 +703,18 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
706
703
  let ctHashes;
707
704
  try {
708
705
  ctHashes = await publicClient.readContract({
709
- address: MocksZkVerifierAddress,
706
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
710
707
  abi: MockZkVerifierAbi,
711
708
  functionName: "zkVerifyCalcCtHashesPacked",
712
709
  args: calcCtHashesArgs
713
710
  });
714
711
  } catch (err) {
715
- throw new CofhesdkError({
712
+ throw new CofheError({
716
713
  code: "ZK_MOCKS_CALC_CT_HASHES_FAILED" /* ZkMocksCalcCtHashesFailed */,
717
714
  message: `mockZkVerifySign calcCtHashes failed while calling zkVerifyCalcCtHashesPacked`,
718
715
  cause: err instanceof Error ? err : void 0,
719
716
  context: {
720
- address: MocksZkVerifierAddress,
717
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
721
718
  items,
722
719
  account,
723
720
  securityZone,
@@ -727,7 +724,7 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
727
724
  });
728
725
  }
729
726
  if (ctHashes.length !== items.length) {
730
- throw new CofhesdkError({
727
+ throw new CofheError({
731
728
  code: "ZK_MOCKS_CALC_CT_HASHES_FAILED" /* ZkMocksCalcCtHashesFailed */,
732
729
  message: `mockZkVerifySign calcCtHashes returned incorrect number of ctHashes`,
733
730
  context: {
@@ -750,7 +747,7 @@ async function insertCtHashes(items, walletClient) {
750
747
  try {
751
748
  const account = walletClient.account;
752
749
  await walletClient.writeContract({
753
- address: MocksZkVerifierAddress,
750
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
754
751
  abi: MockZkVerifierAbi,
755
752
  functionName: "insertPackedCtHashes",
756
753
  args: insertPackedCtHashesArgs,
@@ -758,7 +755,7 @@ async function insertCtHashes(items, walletClient) {
758
755
  account
759
756
  });
760
757
  } catch (err) {
761
- throw new CofhesdkError({
758
+ throw new CofheError({
762
759
  code: "ZK_MOCKS_INSERT_CT_HASHES_FAILED" /* ZkMocksInsertCtHashesFailed */,
763
760
  message: `mockZkVerifySign insertPackedCtHashes failed while calling insertPackedCtHashes`,
764
761
  cause: err instanceof Error ? err : void 0,
@@ -776,7 +773,7 @@ async function createProofSignatures(items, securityZone) {
776
773
  try {
777
774
  encInputSignerClient = createMockZkVerifierSigner();
778
775
  } catch (err) {
779
- throw new CofhesdkError({
776
+ throw new CofheError({
780
777
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
781
778
  message: `mockZkVerifySign createProofSignatures failed while creating wallet client`,
782
779
  cause: err instanceof Error ? err : void 0,
@@ -797,7 +794,7 @@ async function createProofSignatures(items, securityZone) {
797
794
  signatures.push(signature);
798
795
  }
799
796
  } catch (err) {
800
- throw new CofhesdkError({
797
+ throw new CofheError({
801
798
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
802
799
  message: `mockZkVerifySign createProofSignatures failed while calling signMessage`,
803
800
  cause: err instanceof Error ? err : void 0,
@@ -808,7 +805,7 @@ async function createProofSignatures(items, securityZone) {
808
805
  });
809
806
  }
810
807
  if (signatures.length !== items.length) {
811
- throw new CofhesdkError({
808
+ throw new CofheError({
812
809
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
813
810
  message: `mockZkVerifySign createProofSignatures returned incorrect number of signatures`,
814
811
  context: {
@@ -829,46 +826,51 @@ async function cofheMocksZkVerifySign(items, account, securityZone, publicClient
829
826
  signature: signatures[index]
830
827
  }));
831
828
  }
832
- var CofhesdkConfigSchema = z.object({
829
+ var CofheConfigSchema = z.object({
833
830
  /** Environment that the SDK is running in */
834
831
  environment: z.enum(["node", "hardhat", "web", "react"]).optional().default("node"),
835
832
  /** List of supported chain configurations */
836
833
  supportedChains: z.array(z.custom()),
837
- /** How permits are generated */
838
- permitGeneration: z.enum(["ON_CONNECT", "ON_DECRYPT_HANDLES", "MANUAL"]).optional().default("ON_CONNECT"),
839
834
  /** Default permit expiration in seconds, default is 30 days */
840
835
  defaultPermitExpiration: z.number().optional().default(60 * 60 * 24 * 30),
841
836
  /** Storage method for fhe keys (defaults to indexedDB on web, filesystem on node) */
842
837
  fheKeyStorage: z.object({
843
- getItem: z.function().args(z.string()).returns(z.promise(z.any())),
844
- setItem: z.function().args(z.string(), z.any()).returns(z.promise(z.void())),
845
- removeItem: z.function().args(z.string()).returns(z.promise(z.void()))
838
+ getItem: z.custom((val) => typeof val === "function", {
839
+ message: "getItem must be a function"
840
+ }),
841
+ setItem: z.custom((val) => typeof val === "function", {
842
+ message: "setItem must be a function"
843
+ }),
844
+ removeItem: z.custom((val) => typeof val === "function", {
845
+ message: "removeItem must be a function"
846
+ })
846
847
  }).or(z.null()).default(null),
847
848
  /** Whether to use Web Workers for ZK proof generation (web platform only) */
848
849
  useWorkers: z.boolean().optional().default(true),
849
850
  /** Mocks configs */
850
851
  mocks: z.object({
851
- sealOutputDelay: z.number().optional().default(0)
852
- }).optional().default({ sealOutputDelay: 0 }),
852
+ decryptDelay: z.number().optional().default(0),
853
+ encryptDelay: z.union([z.number(), z.tuple([z.number(), z.number(), z.number(), z.number(), z.number()])]).optional().default([100, 100, 100, 500, 500])
854
+ }).optional().default({ decryptDelay: 0, encryptDelay: [100, 100, 100, 500, 500] }),
853
855
  /** Internal configuration */
854
856
  _internal: z.object({
855
857
  zkvWalletClient: z.any().optional()
856
858
  }).optional()
857
859
  });
858
- function createCofhesdkConfigBase(config) {
859
- const result = CofhesdkConfigSchema.safeParse(config);
860
+ function createCofheConfigBase(config) {
861
+ const result = CofheConfigSchema.safeParse(config);
860
862
  if (!result.success) {
861
- throw new Error(`Invalid cofhesdk configuration: ${result.error.message}`);
863
+ throw new Error(`Invalid cofhe configuration: ${z.prettifyError(result.error)}`, { cause: result.error });
862
864
  }
863
865
  return result.data;
864
866
  }
865
- var getCofhesdkConfigItem = (config, key) => {
867
+ var getCofheConfigItem = (config, key) => {
866
868
  return config[key];
867
869
  };
868
870
  function getSupportedChainOrThrow(config, chainId) {
869
871
  const supportedChain = config.supportedChains.find((chain) => chain.id === chainId);
870
872
  if (!supportedChain) {
871
- throw new CofhesdkError({
873
+ throw new CofheError({
872
874
  code: "UNSUPPORTED_CHAIN" /* UnsupportedChain */,
873
875
  message: `Config does not support chain <${chainId}>`,
874
876
  hint: "Ensure config passed to client has been created with this chain in the config.supportedChains array.",
@@ -884,7 +886,7 @@ function getCoFheUrlOrThrow(config, chainId) {
884
886
  const supportedChain = getSupportedChainOrThrow(config, chainId);
885
887
  const url = supportedChain.coFheUrl;
886
888
  if (!url) {
887
- throw new CofhesdkError({
889
+ throw new CofheError({
888
890
  code: "MISSING_CONFIG" /* MissingConfig */,
889
891
  message: `CoFHE URL is not configured for chain <${chainId}>`,
890
892
  hint: "Ensure this chain config includes a coFheUrl property.",
@@ -897,7 +899,7 @@ function getZkVerifierUrlOrThrow(config, chainId) {
897
899
  const supportedChain = getSupportedChainOrThrow(config, chainId);
898
900
  const url = supportedChain.verifierUrl;
899
901
  if (!url) {
900
- throw new CofhesdkError({
902
+ throw new CofheError({
901
903
  code: "ZK_VERIFIER_URL_UNINITIALIZED" /* ZkVerifierUrlUninitialized */,
902
904
  message: `ZK verifier URL is not configured for chain <${chainId}>`,
903
905
  hint: "Ensure this chain config includes a verifierUrl property.",
@@ -910,7 +912,7 @@ function getThresholdNetworkUrlOrThrow(config, chainId) {
910
912
  const supportedChain = getSupportedChainOrThrow(config, chainId);
911
913
  const url = supportedChain.thresholdNetworkUrl;
912
914
  if (!url) {
913
- throw new CofhesdkError({
915
+ throw new CofheError({
914
916
  code: "THRESHOLD_NETWORK_URL_UNINITIALIZED" /* ThresholdNetworkUrlUninitialized */,
915
917
  message: `Threshold network URL is not configured for chain <${chainId}>`,
916
918
  hint: "Ensure this chain config includes a thresholdNetworkUrl property.",
@@ -1122,7 +1124,7 @@ var BaseBuilder = class {
1122
1124
  account;
1123
1125
  constructor(params) {
1124
1126
  if (!params.config) {
1125
- throw new CofhesdkError({
1127
+ throw new CofheError({
1126
1128
  code: "MISSING_CONFIG" /* MissingConfig */,
1127
1129
  message: "Builder config is undefined",
1128
1130
  hint: "Ensure client has been created with a config.",
@@ -1140,12 +1142,12 @@ var BaseBuilder = class {
1140
1142
  }
1141
1143
  /**
1142
1144
  * Asserts that this.chainId is populated
1143
- * @throws {CofhesdkError} If chainId is not set
1145
+ * @throws {CofheError} If chainId is not set
1144
1146
  */
1145
1147
  assertChainId() {
1146
1148
  if (this.chainId)
1147
1149
  return;
1148
- throw new CofhesdkError({
1150
+ throw new CofheError({
1149
1151
  code: "CHAIN_ID_UNINITIALIZED" /* ChainIdUninitialized */,
1150
1152
  message: "Chain ID is not set",
1151
1153
  hint: "Ensure client.connect() has been called and awaited, or use setChainId(...) to set the chainId explicitly.",
@@ -1156,12 +1158,12 @@ var BaseBuilder = class {
1156
1158
  }
1157
1159
  /**
1158
1160
  * Asserts that this.account is populated
1159
- * @throws {CofhesdkError} If account is not set
1161
+ * @throws {CofheError} If account is not set
1160
1162
  */
1161
1163
  assertAccount() {
1162
1164
  if (this.account)
1163
1165
  return;
1164
- throw new CofhesdkError({
1166
+ throw new CofheError({
1165
1167
  code: "ACCOUNT_UNINITIALIZED" /* AccountUninitialized */,
1166
1168
  message: "Account is not set",
1167
1169
  hint: "Ensure client.connect() has been called and awaited, or use setAccount(...) to set the account explicitly.",
@@ -1172,12 +1174,12 @@ var BaseBuilder = class {
1172
1174
  }
1173
1175
  /**
1174
1176
  * Asserts that this.publicClient is populated
1175
- * @throws {CofhesdkError} If publicClient is not set
1177
+ * @throws {CofheError} If publicClient is not set
1176
1178
  */
1177
1179
  assertPublicClient() {
1178
1180
  if (this.publicClient)
1179
1181
  return;
1180
- throw new CofhesdkError({
1182
+ throw new CofheError({
1181
1183
  code: "MISSING_PUBLIC_CLIENT" /* MissingPublicClient */,
1182
1184
  message: "Public client not found",
1183
1185
  hint: "Ensure client.connect() has been called with a publicClient.",
@@ -1188,12 +1190,12 @@ var BaseBuilder = class {
1188
1190
  }
1189
1191
  /**
1190
1192
  * Asserts that this.walletClient is populated
1191
- * @throws {CofhesdkError} If walletClient is not set
1193
+ * @throws {CofheError} If walletClient is not set
1192
1194
  */
1193
1195
  assertWalletClient() {
1194
1196
  if (this.walletClient)
1195
1197
  return;
1196
- throw new CofhesdkError({
1198
+ throw new CofheError({
1197
1199
  code: "MISSING_WALLET_CLIENT" /* MissingWalletClient */,
1198
1200
  message: "Wallet client not found",
1199
1201
  hint: "Ensure client.connect() has been called with a walletClient.",
@@ -1238,7 +1240,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1238
1240
  this.securityZone = params.securityZone ?? 0;
1239
1241
  this.zkvWalletClient = params.zkvWalletClient;
1240
1242
  if (!params.tfhePublicKeyDeserializer) {
1241
- throw new CofhesdkError({
1243
+ throw new CofheError({
1242
1244
  code: "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER" /* MissingTfhePublicKeyDeserializer */,
1243
1245
  message: "EncryptInputsBuilder tfhePublicKeyDeserializer is undefined",
1244
1246
  hint: "Ensure client has been created with a tfhePublicKeyDeserializer.",
@@ -1249,7 +1251,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1249
1251
  }
1250
1252
  this.tfhePublicKeyDeserializer = params.tfhePublicKeyDeserializer;
1251
1253
  if (!params.compactPkeCrsDeserializer) {
1252
- throw new CofhesdkError({
1254
+ throw new CofheError({
1253
1255
  code: "MISSING_COMPACT_PKE_CRS_DESERIALIZER" /* MissingCompactPkeCrsDeserializer */,
1254
1256
  message: "EncryptInputsBuilder compactPkeCrsDeserializer is undefined",
1255
1257
  hint: "Ensure client has been created with a compactPkeCrsDeserializer.",
@@ -1260,7 +1262,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1260
1262
  }
1261
1263
  this.compactPkeCrsDeserializer = params.compactPkeCrsDeserializer;
1262
1264
  if (!params.zkBuilderAndCrsGenerator) {
1263
- throw new CofhesdkError({
1265
+ throw new CofheError({
1264
1266
  code: "MISSING_ZK_BUILDER_AND_CRS_GENERATOR" /* MissingZkBuilderAndCrsGenerator */,
1265
1267
  message: "EncryptInputsBuilder zkBuilderAndCrsGenerator is undefined",
1266
1268
  hint: "Ensure client has been created with a zkBuilderAndCrsGenerator.",
@@ -1284,7 +1286,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1284
1286
  * ```typescript
1285
1287
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1286
1288
  * .setAccount("0x123")
1287
- * .encrypt();
1289
+ * .execute();
1288
1290
  * ```
1289
1291
  *
1290
1292
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1305,7 +1307,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1305
1307
  * ```typescript
1306
1308
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1307
1309
  * .setChainId(11155111)
1308
- * .encrypt();
1310
+ * .execute();
1309
1311
  * ```
1310
1312
  *
1311
1313
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1326,7 +1328,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1326
1328
  * ```typescript
1327
1329
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1328
1330
  * .setSecurityZone(1)
1329
- * .encrypt();
1331
+ * .execute();
1330
1332
  * ```
1331
1333
  *
1332
1334
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1347,7 +1349,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1347
1349
  * ```typescript
1348
1350
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1349
1351
  * .setUseWorker(false)
1350
- * .encrypt();
1352
+ * .execute();
1351
1353
  * ```
1352
1354
  *
1353
1355
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1381,13 +1383,13 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1381
1383
  * Example:
1382
1384
  * ```typescript
1383
1385
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1384
- * .setStepCallback((step: EncryptStep) => console.log(step))
1385
- * .encrypt();
1386
+ * .onStep((step: EncryptStep) => console.log(step))
1387
+ * .execute();
1386
1388
  * ```
1387
1389
  *
1388
1390
  * @returns The EncryptInputsBuilder instance.
1389
1391
  */
1390
- setStepCallback(callback) {
1392
+ onStep(callback) {
1391
1393
  this.stepCallback = callback;
1392
1394
  return this;
1393
1395
  }
@@ -1410,7 +1412,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1410
1412
  this.stepCallback(step, { ...context, isStart: false, isEnd: true, duration });
1411
1413
  }
1412
1414
  /**
1413
- * zkVerifierUrl is included in the chains exported from cofhesdk/chains for use in CofhesdkConfig.supportedChains
1415
+ * zkVerifierUrl is included in the chains exported from @cofhe/sdk/chains for use in CofheConfig.supportedChains
1414
1416
  * Users should generally not set this manually.
1415
1417
  */
1416
1418
  async getZkVerifierUrl() {
@@ -1418,7 +1420,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1418
1420
  return getZkVerifierUrlOrThrow(this.config, this.chainId);
1419
1421
  }
1420
1422
  /**
1421
- * initTfhe is a platform-specific dependency injected into core/createCofhesdkClientBase by web/createCofhesdkClient and node/createCofhesdkClient
1423
+ * initTfhe is a platform-specific dependency injected into core/createCofheClientBase by web/createCofheClient and node/createCofheClient
1422
1424
  * web/ uses zama "tfhe"
1423
1425
  * node/ uses zama "node-tfhe"
1424
1426
  * Users should not set this manually.
@@ -1429,7 +1431,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1429
1431
  try {
1430
1432
  return await this.initTfhe();
1431
1433
  } catch (error) {
1432
- throw CofhesdkError.fromError(error, {
1434
+ throw CofheError.fromError(error, {
1433
1435
  code: "INIT_TFHE_FAILED" /* InitTfheFailed */,
1434
1436
  message: `Failed to initialize TFHE`,
1435
1437
  context: {
@@ -1448,7 +1450,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1448
1450
  try {
1449
1451
  await this.keysStorage?.rehydrateKeysStore();
1450
1452
  } catch (error) {
1451
- throw CofhesdkError.fromError(error, {
1453
+ throw CofheError.fromError(error, {
1452
1454
  code: "REHYDRATE_KEYS_STORE_FAILED" /* RehydrateKeysStoreFailed */,
1453
1455
  message: `Failed to rehydrate keys store`,
1454
1456
  context: {
@@ -1470,7 +1472,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1470
1472
  this.keysStorage
1471
1473
  );
1472
1474
  } catch (error) {
1473
- throw CofhesdkError.fromError(error, {
1475
+ throw CofheError.fromError(error, {
1474
1476
  code: "FETCH_KEYS_FAILED" /* FetchKeysFailed */,
1475
1477
  message: `Failed to fetch FHE key and CRS`,
1476
1478
  context: {
@@ -1483,7 +1485,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1483
1485
  });
1484
1486
  }
1485
1487
  if (!fheKey) {
1486
- throw new CofhesdkError({
1488
+ throw new CofheError({
1487
1489
  code: "MISSING_FHE_KEY" /* MissingFheKey */,
1488
1490
  message: `FHE key not found`,
1489
1491
  context: {
@@ -1493,7 +1495,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1493
1495
  });
1494
1496
  }
1495
1497
  if (!crs) {
1496
- throw new CofhesdkError({
1498
+ throw new CofheError({
1497
1499
  code: "MISSING_CRS" /* MissingCrs */,
1498
1500
  message: `CRS not found for chainId <${this.chainId}>`,
1499
1501
  context: {
@@ -1503,6 +1505,17 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1503
1505
  }
1504
1506
  return { fheKey, fheKeyFetchedFromCoFHE, crs, crsFetchedFromCoFHE };
1505
1507
  }
1508
+ /**
1509
+ * Resolves the encryptDelay config into an array of 5 per-step delays.
1510
+ * A single number is broadcast to all steps; a tuple is used as-is.
1511
+ */
1512
+ resolveEncryptDelays() {
1513
+ const encryptDelay = this.config?.mocks?.encryptDelay ?? [100, 100, 100, 500, 500];
1514
+ if (typeof encryptDelay === "number") {
1515
+ return [encryptDelay, encryptDelay, encryptDelay, encryptDelay, encryptDelay];
1516
+ }
1517
+ return encryptDelay;
1518
+ }
1506
1519
  /**
1507
1520
  * @dev Encrypt against the cofheMocks instead of CoFHE
1508
1521
  *
@@ -1510,25 +1523,35 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1510
1523
  * cofheMocksInsertPackedHashes - stores the ctHashes and their plaintext values for on-chain mocking of FHE operations.
1511
1524
  * cofheMocksZkCreateProofSignatures - creates signatures to be included in the encrypted inputs. The signers address is known and verified in the mock contracts.
1512
1525
  */
1513
- async mocksEncrypt() {
1526
+ async mocksExecute() {
1514
1527
  this.assertAccount();
1515
1528
  this.assertPublicClient();
1516
1529
  this.assertWalletClient();
1530
+ const [initTfheDelay, fetchKeysDelay, packDelay, proveDelay, verifyDelay] = this.resolveEncryptDelays();
1517
1531
  this.fireStepStart("initTfhe" /* InitTfhe */);
1518
- await sleep(100);
1519
- this.fireStepEnd("initTfhe" /* InitTfhe */, { tfheInitializationExecuted: false });
1532
+ await sleep(initTfheDelay);
1533
+ this.fireStepEnd("initTfhe" /* InitTfhe */, {
1534
+ tfheInitializationExecuted: false,
1535
+ isMocks: true,
1536
+ mockSleep: initTfheDelay
1537
+ });
1520
1538
  this.fireStepStart("fetchKeys" /* FetchKeys */);
1521
- await sleep(100);
1522
- this.fireStepEnd("fetchKeys" /* FetchKeys */, { fheKeyFetchedFromCoFHE: false, crsFetchedFromCoFHE: false });
1539
+ await sleep(fetchKeysDelay);
1540
+ this.fireStepEnd("fetchKeys" /* FetchKeys */, {
1541
+ fheKeyFetchedFromCoFHE: false,
1542
+ crsFetchedFromCoFHE: false,
1543
+ isMocks: true,
1544
+ mockSleep: fetchKeysDelay
1545
+ });
1523
1546
  this.fireStepStart("pack" /* Pack */);
1524
1547
  await cofheMocksCheckEncryptableBits(this.inputItems);
1525
- await sleep(100);
1526
- this.fireStepEnd("pack" /* Pack */);
1548
+ await sleep(packDelay);
1549
+ this.fireStepEnd("pack" /* Pack */, { isMocks: true, mockSleep: packDelay });
1527
1550
  this.fireStepStart("prove" /* Prove */);
1528
- await sleep(500);
1529
- this.fireStepEnd("prove" /* Prove */);
1551
+ await sleep(proveDelay);
1552
+ this.fireStepEnd("prove" /* Prove */, { isMocks: true, mockSleep: proveDelay });
1530
1553
  this.fireStepStart("verify" /* Verify */);
1531
- await sleep(500);
1554
+ await sleep(verifyDelay);
1532
1555
  const signedResults = await cofheMocksZkVerifySign(
1533
1556
  this.inputItems,
1534
1557
  this.account,
@@ -1543,13 +1566,13 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1543
1566
  utype: this.inputItems[index].utype,
1544
1567
  signature
1545
1568
  }));
1546
- this.fireStepEnd("verify" /* Verify */);
1569
+ this.fireStepEnd("verify" /* Verify */, { isMocks: true, mockSleep: verifyDelay });
1547
1570
  return encryptedInputs;
1548
1571
  }
1549
1572
  /**
1550
1573
  * In the production context, perform a true encryption with the CoFHE coprocessor.
1551
1574
  */
1552
- async productionEncrypt() {
1575
+ async productionExecute() {
1553
1576
  this.assertAccount();
1554
1577
  this.assertChainId();
1555
1578
  this.fireStepStart("initTfhe" /* InitTfhe */);
@@ -1612,22 +1635,22 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1612
1635
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1613
1636
  * .setAccount('0x123...890') // optional
1614
1637
  * .setChainId(11155111) // optional
1615
- * .encrypt(); // execute
1638
+ * .execute(); // execute
1616
1639
  * ```
1617
1640
  *
1618
1641
  * @returns The encrypted inputs.
1619
1642
  */
1620
- async encrypt() {
1643
+ async execute() {
1621
1644
  if (this.chainId === hardhat.id)
1622
- return this.mocksEncrypt();
1623
- return this.productionEncrypt();
1645
+ return this.mocksExecute();
1646
+ return this.productionExecute();
1624
1647
  }
1625
1648
  };
1626
1649
  var storeActivePermit = async (permit, publicClient, walletClient) => {
1627
1650
  const chainId = await publicClient.getChainId();
1628
1651
  const account = walletClient.account.address;
1629
1652
  permitStore.setPermit(chainId, account, permit);
1630
- permitStore.setActivePermitHash(chainId, account, PermitUtils.getHash(permit));
1653
+ permitStore.setActivePermitHash(chainId, account, permit.hash);
1631
1654
  };
1632
1655
  var createPermitWithSign = async (options, publicClient, walletClient, permitMethod) => {
1633
1656
  const permit = await permitMethod(options, publicClient, walletClient);
@@ -1685,7 +1708,7 @@ var getOrCreateSharingPermit = async (publicClient, walletClient, options, chain
1685
1708
  }
1686
1709
  return createSharing(options, publicClient, walletClient);
1687
1710
  };
1688
- var removePermit = async (chainId, account, hash, force) => permitStore.removePermit(chainId, account, hash, force);
1711
+ var removePermit = async (chainId, account, hash) => permitStore.removePermit(chainId, account, hash);
1689
1712
  var removeActivePermit = async (chainId, account) => permitStore.removeActivePermitHash(chainId, account);
1690
1713
  var permits = {
1691
1714
  getSnapshot: permitStore.store.getState,
@@ -1725,8 +1748,8 @@ var convertViaUtype = (utype, value) => {
1725
1748
  }
1726
1749
  };
1727
1750
 
1728
- // core/decrypt/MockQueryDecrypterAbi.ts
1729
- var MockQueryDecrypterAbi = [
1751
+ // core/decrypt/MockThresholdNetworkAbi.ts
1752
+ var MockThresholdNetworkAbi = [
1730
1753
  {
1731
1754
  type: "function",
1732
1755
  name: "acl",
@@ -1773,11 +1796,7 @@ var MockQueryDecrypterAbi = [
1773
1796
  { name: "expiration", type: "uint64", internalType: "uint64" },
1774
1797
  { name: "recipient", type: "address", internalType: "address" },
1775
1798
  { name: "validatorId", type: "uint256", internalType: "uint256" },
1776
- {
1777
- name: "validatorContract",
1778
- type: "address",
1779
- internalType: "address"
1780
- },
1799
+ { name: "validatorContract", type: "address", internalType: "address" },
1781
1800
  { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
1782
1801
  { name: "issuerSignature", type: "bytes", internalType: "bytes" },
1783
1802
  { name: "recipientSignature", type: "bytes", internalType: "bytes" }
@@ -1806,11 +1825,7 @@ var MockQueryDecrypterAbi = [
1806
1825
  { name: "expiration", type: "uint64", internalType: "uint64" },
1807
1826
  { name: "recipient", type: "address", internalType: "address" },
1808
1827
  { name: "validatorId", type: "uint256", internalType: "uint256" },
1809
- {
1810
- name: "validatorContract",
1811
- type: "address",
1812
- internalType: "address"
1813
- },
1828
+ { name: "validatorContract", type: "address", internalType: "address" },
1814
1829
  { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
1815
1830
  { name: "issuerSignature", type: "bytes", internalType: "bytes" },
1816
1831
  { name: "recipientSignature", type: "bytes", internalType: "bytes" }
@@ -1834,13 +1849,6 @@ var MockQueryDecrypterAbi = [
1834
1849
  outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
1835
1850
  stateMutability: "pure"
1836
1851
  },
1837
- {
1838
- type: "function",
1839
- name: "taskManager",
1840
- inputs: [],
1841
- outputs: [{ name: "", type: "address", internalType: "contract TaskManager" }],
1842
- stateMutability: "view"
1843
- },
1844
1852
  {
1845
1853
  type: "function",
1846
1854
  name: "unseal",
@@ -1851,16 +1859,80 @@ var MockQueryDecrypterAbi = [
1851
1859
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
1852
1860
  stateMutability: "pure"
1853
1861
  },
1854
- { type: "error", name: "NotAllowed", inputs: [] },
1855
- { type: "error", name: "SealingKeyInvalid", inputs: [] },
1856
- { type: "error", name: "SealingKeyMissing", inputs: [] }
1862
+ {
1863
+ type: "function",
1864
+ name: "mockAcl",
1865
+ inputs: [],
1866
+ outputs: [{ name: "", type: "address", internalType: "contract MockACL" }],
1867
+ stateMutability: "view"
1868
+ },
1869
+ {
1870
+ type: "function",
1871
+ name: "mockTaskManager",
1872
+ inputs: [],
1873
+ outputs: [{ name: "", type: "address", internalType: "contract MockTaskManager" }],
1874
+ stateMutability: "view"
1875
+ },
1876
+ {
1877
+ type: "function",
1878
+ name: "mockQueryDecrypt",
1879
+ inputs: [
1880
+ { name: "ctHash", type: "uint256", internalType: "uint256" },
1881
+ { name: "", type: "uint256", internalType: "uint256" },
1882
+ { name: "issuer", type: "address", internalType: "address" }
1883
+ ],
1884
+ outputs: [
1885
+ { name: "allowed", type: "bool", internalType: "bool" },
1886
+ { name: "error", type: "string", internalType: "string" },
1887
+ { name: "", type: "uint256", internalType: "uint256" }
1888
+ ],
1889
+ stateMutability: "view"
1890
+ },
1891
+ {
1892
+ type: "function",
1893
+ name: "decryptForTxWithPermit",
1894
+ inputs: [
1895
+ { name: "ctHash", type: "uint256", internalType: "uint256" },
1896
+ {
1897
+ name: "permission",
1898
+ type: "tuple",
1899
+ internalType: "struct Permission",
1900
+ components: [
1901
+ { name: "issuer", type: "address", internalType: "address" },
1902
+ { name: "expiration", type: "uint64", internalType: "uint64" },
1903
+ { name: "recipient", type: "address", internalType: "address" },
1904
+ { name: "validatorId", type: "uint256", internalType: "uint256" },
1905
+ { name: "validatorContract", type: "address", internalType: "address" },
1906
+ { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
1907
+ { name: "issuerSignature", type: "bytes", internalType: "bytes" },
1908
+ { name: "recipientSignature", type: "bytes", internalType: "bytes" }
1909
+ ]
1910
+ }
1911
+ ],
1912
+ outputs: [
1913
+ { name: "allowed", type: "bool", internalType: "bool" },
1914
+ { name: "error", type: "string", internalType: "string" },
1915
+ { name: "decryptedValue", type: "uint256", internalType: "uint256" }
1916
+ ],
1917
+ stateMutability: "view"
1918
+ },
1919
+ {
1920
+ type: "function",
1921
+ name: "decryptForTxWithoutPermit",
1922
+ inputs: [{ name: "ctHash", type: "uint256", internalType: "uint256" }],
1923
+ outputs: [
1924
+ { name: "allowed", type: "bool", internalType: "bool" },
1925
+ { name: "error", type: "string", internalType: "string" },
1926
+ { name: "decryptedValue", type: "uint256", internalType: "uint256" }
1927
+ ],
1928
+ stateMutability: "view"
1929
+ }
1857
1930
  ];
1858
1931
 
1859
- // core/decrypt/cofheMocksSealOutput.ts
1860
- var MockQueryDecrypterAddress = "0x0000000000000000000000000000000000000200";
1861
- async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSealOutputDelay) {
1862
- if (mocksSealOutputDelay > 0)
1863
- await sleep(mocksSealOutputDelay);
1932
+ // core/decrypt/cofheMocksDecryptForView.ts
1933
+ async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient, mocksDecryptDelay) {
1934
+ if (mocksDecryptDelay > 0)
1935
+ await sleep(mocksDecryptDelay);
1864
1936
  const permission = PermitUtils.getPermission(permit, true);
1865
1937
  const permissionWithBigInts = {
1866
1938
  ...permission,
@@ -1868,19 +1940,19 @@ async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSe
1868
1940
  validatorId: BigInt(permission.validatorId)
1869
1941
  };
1870
1942
  const [allowed, error, result] = await publicClient.readContract({
1871
- address: MockQueryDecrypterAddress,
1872
- abi: MockQueryDecrypterAbi,
1943
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
1944
+ abi: MockThresholdNetworkAbi,
1873
1945
  functionName: "querySealOutput",
1874
1946
  args: [ctHash, BigInt(utype), permissionWithBigInts]
1875
1947
  });
1876
1948
  if (error != "") {
1877
- throw new CofhesdkError({
1949
+ throw new CofheError({
1878
1950
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
1879
1951
  message: `mocks querySealOutput call failed: ${error}`
1880
1952
  });
1881
1953
  }
1882
1954
  if (allowed == false) {
1883
- throw new CofhesdkError({
1955
+ throw new CofheError({
1884
1956
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
1885
1957
  message: `mocks querySealOutput call failed: ACL Access Denied (NotAllowed)`
1886
1958
  });
@@ -1899,7 +1971,7 @@ function numberArrayToUint8Array(arr) {
1899
1971
  }
1900
1972
  function convertSealedData(sealed) {
1901
1973
  if (!sealed) {
1902
- throw new CofhesdkError({
1974
+ throw new CofheError({
1903
1975
  code: "SEAL_OUTPUT_RETURNED_NULL" /* SealOutputReturnedNull */,
1904
1976
  message: "Sealed data is missing from completed response"
1905
1977
  });
@@ -1926,7 +1998,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
1926
1998
  body: JSON.stringify(body)
1927
1999
  });
1928
2000
  } catch (e) {
1929
- throw new CofhesdkError({
2001
+ throw new CofheError({
1930
2002
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
1931
2003
  message: `sealOutput request failed`,
1932
2004
  hint: "Ensure the threshold network URL is valid and reachable.",
@@ -1945,7 +2017,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
1945
2017
  } catch {
1946
2018
  errorMessage = response.statusText || errorMessage;
1947
2019
  }
1948
- throw new CofhesdkError({
2020
+ throw new CofheError({
1949
2021
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
1950
2022
  message: `sealOutput request failed: ${errorMessage}`,
1951
2023
  hint: "Check the threshold network URL and request parameters.",
@@ -1961,7 +2033,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
1961
2033
  try {
1962
2034
  submitResponse = await response.json();
1963
2035
  } catch (e) {
1964
- throw new CofhesdkError({
2036
+ throw new CofheError({
1965
2037
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
1966
2038
  message: `Failed to parse sealOutput submit response`,
1967
2039
  cause: e instanceof Error ? e : void 0,
@@ -1972,7 +2044,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
1972
2044
  });
1973
2045
  }
1974
2046
  if (!submitResponse.request_id) {
1975
- throw new CofhesdkError({
2047
+ throw new CofheError({
1976
2048
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
1977
2049
  message: `sealOutput submit response missing request_id`,
1978
2050
  context: {
@@ -1989,7 +2061,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
1989
2061
  let completed = false;
1990
2062
  while (!completed) {
1991
2063
  if (Date.now() - startTime > POLL_TIMEOUT_MS) {
1992
- throw new CofhesdkError({
2064
+ throw new CofheError({
1993
2065
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
1994
2066
  message: `sealOutput polling timed out after ${POLL_TIMEOUT_MS}ms`,
1995
2067
  hint: "The request may still be processing. Try again later.",
@@ -2009,7 +2081,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2009
2081
  }
2010
2082
  });
2011
2083
  } catch (e) {
2012
- throw new CofhesdkError({
2084
+ throw new CofheError({
2013
2085
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2014
2086
  message: `sealOutput status poll failed`,
2015
2087
  hint: "Ensure the threshold network URL is valid and reachable.",
@@ -2021,7 +2093,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2021
2093
  });
2022
2094
  }
2023
2095
  if (response.status === 404) {
2024
- throw new CofhesdkError({
2096
+ throw new CofheError({
2025
2097
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2026
2098
  message: `sealOutput request not found: ${requestId}`,
2027
2099
  hint: "The request may have expired or been invalid.",
@@ -2039,7 +2111,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2039
2111
  } catch {
2040
2112
  errorMessage = response.statusText || errorMessage;
2041
2113
  }
2042
- throw new CofhesdkError({
2114
+ throw new CofheError({
2043
2115
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2044
2116
  message: `sealOutput status poll failed: ${errorMessage}`,
2045
2117
  context: {
@@ -2054,7 +2126,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2054
2126
  try {
2055
2127
  statusResponse = await response.json();
2056
2128
  } catch (e) {
2057
- throw new CofhesdkError({
2129
+ throw new CofheError({
2058
2130
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2059
2131
  message: `Failed to parse sealOutput status response`,
2060
2132
  cause: e instanceof Error ? e : void 0,
@@ -2067,7 +2139,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2067
2139
  if (statusResponse.status === "COMPLETED") {
2068
2140
  if (statusResponse.is_succeed === false) {
2069
2141
  const errorMessage = statusResponse.error_message || "Unknown error";
2070
- throw new CofhesdkError({
2142
+ throw new CofheError({
2071
2143
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2072
2144
  message: `sealOutput request failed: ${errorMessage}`,
2073
2145
  context: {
@@ -2078,7 +2150,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2078
2150
  });
2079
2151
  }
2080
2152
  if (!statusResponse.sealed) {
2081
- throw new CofhesdkError({
2153
+ throw new CofheError({
2082
2154
  code: "SEAL_OUTPUT_RETURNED_NULL" /* SealOutputReturnedNull */,
2083
2155
  message: `sealOutput request completed but returned no sealed data`,
2084
2156
  context: {
@@ -2092,7 +2164,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2092
2164
  }
2093
2165
  await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
2094
2166
  }
2095
- throw new CofhesdkError({
2167
+ throw new CofheError({
2096
2168
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2097
2169
  message: "Polling loop exited unexpectedly",
2098
2170
  context: {
@@ -2105,9 +2177,99 @@ async function tnSealOutputV2(ctHash, chainId, permission, thresholdNetworkUrl)
2105
2177
  const requestId = await submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission);
2106
2178
  return await pollSealOutputStatus(thresholdNetworkUrl, requestId);
2107
2179
  }
2180
+ async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient, mocksDecryptForTxDelay) {
2181
+ if (mocksDecryptForTxDelay > 0)
2182
+ await sleep(mocksDecryptForTxDelay);
2183
+ if (permit !== null) {
2184
+ let permission = PermitUtils.getPermission(permit, true);
2185
+ const permissionWithBigInts = {
2186
+ ...permission,
2187
+ expiration: BigInt(permission.expiration),
2188
+ validatorId: BigInt(permission.validatorId)
2189
+ };
2190
+ const [allowed2, error2, result2] = await publicClient.readContract({
2191
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
2192
+ abi: MockThresholdNetworkAbi,
2193
+ functionName: "decryptForTxWithPermit",
2194
+ args: [ctHash, permissionWithBigInts]
2195
+ });
2196
+ if (error2 != "") {
2197
+ throw new CofheError({
2198
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
2199
+ message: `mocks decryptForTx call failed: ${error2}`
2200
+ });
2201
+ }
2202
+ if (allowed2 == false) {
2203
+ throw new CofheError({
2204
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
2205
+ message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
2206
+ });
2207
+ }
2208
+ const chainId2 = await publicClient.getChainId();
2209
+ const ctHashBigInt2 = BigInt(ctHash);
2210
+ const resultBigInt2 = BigInt(result2);
2211
+ const encryptionType2 = Number((ctHashBigInt2 & 0x7fn << 8n) >> 8n);
2212
+ const ctHashBytes322 = pad(toHex(ctHashBigInt2), { size: 32 });
2213
+ const packed2 = encodePacked(
2214
+ ["uint256", "uint32", "uint64", "bytes32"],
2215
+ [resultBigInt2, encryptionType2, BigInt(chainId2), ctHashBytes322]
2216
+ );
2217
+ const messageHash2 = keccak256(packed2);
2218
+ const signatureHex2 = await sign({
2219
+ hash: messageHash2,
2220
+ privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
2221
+ to: "hex"
2222
+ });
2223
+ const signature2 = signatureHex2.slice(2);
2224
+ return {
2225
+ ctHash,
2226
+ decryptedValue: BigInt(result2),
2227
+ signature: signature2
2228
+ };
2229
+ }
2230
+ const [allowed, error, result] = await publicClient.readContract({
2231
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
2232
+ abi: MockThresholdNetworkAbi,
2233
+ functionName: "decryptForTxWithoutPermit",
2234
+ args: [ctHash]
2235
+ });
2236
+ if (error != "") {
2237
+ throw new CofheError({
2238
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
2239
+ message: `mocks decryptForTx call failed: ${error}`
2240
+ });
2241
+ }
2242
+ if (allowed == false) {
2243
+ throw new CofheError({
2244
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
2245
+ message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
2246
+ });
2247
+ }
2248
+ const chainId = await publicClient.getChainId();
2249
+ const ctHashBigInt = BigInt(ctHash);
2250
+ const resultBigInt = BigInt(result);
2251
+ const encryptionType = Number((ctHashBigInt & 0x7fn << 8n) >> 8n);
2252
+ const ctHashBytes32 = pad(toHex(ctHashBigInt), { size: 32 });
2253
+ const packed = encodePacked(
2254
+ ["uint256", "uint32", "uint64", "bytes32"],
2255
+ [resultBigInt, encryptionType, BigInt(chainId), ctHashBytes32]
2256
+ );
2257
+ const messageHash = keccak256(packed);
2258
+ const signatureHex = await sign({
2259
+ hash: messageHash,
2260
+ privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
2261
+ to: "hex"
2262
+ });
2263
+ const signature = signatureHex.slice(2);
2264
+ return {
2265
+ ctHash,
2266
+ decryptedValue: BigInt(result),
2267
+ signature
2268
+ };
2269
+ }
2108
2270
 
2109
- // core/decrypt/decryptHandleBuilder.ts
2110
- var DecryptHandlesBuilder = class extends BaseBuilder {
2271
+ // core/decrypt/decryptForViewBuilder.ts
2272
+ var DecryptForViewBuilder = class extends BaseBuilder {
2111
2273
  ctHash;
2112
2274
  utype;
2113
2275
  permitHash;
@@ -2133,12 +2295,12 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2133
2295
  *
2134
2296
  * Example:
2135
2297
  * ```typescript
2136
- * const unsealed = await decryptHandle(ctHash, utype)
2298
+ * const unsealed = await client.decryptForView(ctHash, utype)
2137
2299
  * .setChainId(11155111)
2138
- * .decrypt();
2300
+ * .execute();
2139
2301
  * ```
2140
2302
  *
2141
- * @returns The chainable DecryptHandlesBuilder instance.
2303
+ * @returns The chainable DecryptForViewBuilder instance.
2142
2304
  */
2143
2305
  setChainId(chainId) {
2144
2306
  this.chainId = chainId;
@@ -2154,12 +2316,12 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2154
2316
  *
2155
2317
  * Example:
2156
2318
  * ```typescript
2157
- * const unsealed = await decryptHandle(ctHash, utype)
2319
+ * const unsealed = await client.decryptForView(ctHash, utype)
2158
2320
  * .setAccount('0x1234567890123456789012345678901234567890')
2159
- * .decrypt();
2321
+ * .execute();
2160
2322
  * ```
2161
2323
  *
2162
- * @returns The chainable DecryptHandlesBuilder instance.
2324
+ * @returns The chainable DecryptForViewBuilder instance.
2163
2325
  */
2164
2326
  setAccount(account) {
2165
2327
  this.account = account;
@@ -2168,6 +2330,19 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2168
2330
  getAccount() {
2169
2331
  return this.account;
2170
2332
  }
2333
+ withPermit(permitOrPermitHash) {
2334
+ if (typeof permitOrPermitHash === "string") {
2335
+ this.permitHash = permitOrPermitHash;
2336
+ this.permit = void 0;
2337
+ } else if (permitOrPermitHash === void 0) {
2338
+ this.permitHash = void 0;
2339
+ this.permit = void 0;
2340
+ } else {
2341
+ this.permit = permitOrPermitHash;
2342
+ this.permitHash = void 0;
2343
+ }
2344
+ return this;
2345
+ }
2171
2346
  /**
2172
2347
  * @param permitHash - Permit hash to decrypt values from. Used to fetch the correct permit.
2173
2348
  *
@@ -2176,16 +2351,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2176
2351
  *
2177
2352
  * Example:
2178
2353
  * ```typescript
2179
- * const unsealed = await decryptHandle(ctHash, utype)
2354
+ * const unsealed = await client.decryptForView(ctHash, utype)
2180
2355
  * .setPermitHash('0x1234567890123456789012345678901234567890')
2181
- * .decrypt();
2356
+ * .execute();
2182
2357
  * ```
2183
2358
  *
2184
- * @returns The chainable DecryptHandlesBuilder instance.
2359
+ * @returns The chainable DecryptForViewBuilder instance.
2185
2360
  */
2361
+ /** @deprecated Use `withPermit(permitHash)` instead. */
2186
2362
  setPermitHash(permitHash) {
2187
- this.permitHash = permitHash;
2188
- return this;
2363
+ return this.withPermit(permitHash);
2189
2364
  }
2190
2365
  getPermitHash() {
2191
2366
  return this.permitHash;
@@ -2197,16 +2372,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2197
2372
  *
2198
2373
  * Example:
2199
2374
  * ```typescript
2200
- * const unsealed = await decryptHandle(ctHash, utype)
2375
+ * const unsealed = await client.decryptForView(ctHash, utype)
2201
2376
  * .setPermit(permit)
2202
- * .decrypt();
2377
+ * .execute();
2203
2378
  * ```
2204
2379
  *
2205
- * @returns The chainable DecryptHandlesBuilder instance.
2380
+ * @returns The chainable DecryptForViewBuilder instance.
2206
2381
  */
2382
+ /** @deprecated Use `withPermit(permit)` instead. */
2207
2383
  setPermit(permit) {
2208
- this.permit = permit;
2209
- return this;
2384
+ return this.withPermit(permit);
2210
2385
  }
2211
2386
  getPermit() {
2212
2387
  return this.permit;
@@ -2217,7 +2392,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2217
2392
  }
2218
2393
  validateUtypeOrThrow() {
2219
2394
  if (!isValidUtype(this.utype))
2220
- throw new CofhesdkError({
2395
+ throw new CofheError({
2221
2396
  code: "INVALID_UTYPE" /* InvalidUtype */,
2222
2397
  message: `Invalid utype to decrypt to`,
2223
2398
  context: {
@@ -2233,7 +2408,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2233
2408
  if (this.permitHash) {
2234
2409
  const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
2235
2410
  if (!permit2) {
2236
- throw new CofhesdkError({
2411
+ throw new CofheError({
2237
2412
  code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
2238
2413
  message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
2239
2414
  hint: "Ensure the permit exists and is valid.",
@@ -2248,7 +2423,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2248
2423
  }
2249
2424
  const permit = await permits.getActivePermit(this.chainId, this.account);
2250
2425
  if (!permit) {
2251
- throw new CofhesdkError({
2426
+ throw new CofheError({
2252
2427
  code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
2253
2428
  message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
2254
2429
  hint: "Ensure a permit exists for this account on this chain.",
@@ -2265,8 +2440,8 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2265
2440
  */
2266
2441
  async mocksSealOutput(permit) {
2267
2442
  this.assertPublicClient();
2268
- const mocksSealOutputDelay = this.config.mocks.sealOutputDelay;
2269
- return cofheMocksSealOutput(this.ctHash, this.utype, permit, this.publicClient, mocksSealOutputDelay);
2443
+ const mocksDecryptDelay = this.config.mocks.decryptDelay;
2444
+ return cofheMocksDecryptForView(this.ctHash, this.utype, permit, this.publicClient, mocksDecryptDelay);
2270
2445
  }
2271
2446
  /**
2272
2447
  * In the production context, perform a true decryption with the CoFHE coprocessor.
@@ -2291,15 +2466,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2291
2466
  *
2292
2467
  * Example:
2293
2468
  * ```typescript
2294
- * const unsealed = await decryptHandle(ctHash, utype)
2469
+ * const unsealed = await client.decryptForView(ctHash, utype)
2295
2470
  * .setChainId(11155111) // optional
2296
2471
  * .setAccount('0x123...890') // optional
2297
- * .decrypt(); // execute
2472
+ * .withPermit() // optional
2473
+ * .execute(); // execute
2298
2474
  * ```
2299
2475
  *
2300
2476
  * @returns The unsealed item.
2301
2477
  */
2302
- async decrypt() {
2478
+ async execute() {
2303
2479
  this.validateUtypeOrThrow();
2304
2480
  const permit = await this.getResolvedPermit();
2305
2481
  PermitUtils.validate(permit);
@@ -2315,6 +2491,394 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2315
2491
  }
2316
2492
  };
2317
2493
 
2494
+ // core/decrypt/tnDecrypt.ts
2495
+ function normalizeSignature(signature) {
2496
+ if (typeof signature !== "string") {
2497
+ throw new CofheError({
2498
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
2499
+ message: "decrypt response missing signature",
2500
+ context: {
2501
+ signature
2502
+ }
2503
+ });
2504
+ }
2505
+ const trimmed = signature.trim();
2506
+ if (trimmed.length === 0) {
2507
+ throw new CofheError({
2508
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
2509
+ message: "decrypt response returned empty signature"
2510
+ });
2511
+ }
2512
+ return trimmed.startsWith("0x") ? trimmed.slice(2) : trimmed;
2513
+ }
2514
+ function parseDecryptedBytesToBigInt(decrypted) {
2515
+ if (!Array.isArray(decrypted)) {
2516
+ throw new CofheError({
2517
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
2518
+ message: "decrypt response field <decrypted> must be a byte array",
2519
+ context: {
2520
+ decrypted
2521
+ }
2522
+ });
2523
+ }
2524
+ if (decrypted.length === 0) {
2525
+ throw new CofheError({
2526
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
2527
+ message: "decrypt response field <decrypted> was an empty byte array",
2528
+ context: {
2529
+ decrypted
2530
+ }
2531
+ });
2532
+ }
2533
+ let hex = "";
2534
+ for (const b of decrypted) {
2535
+ if (typeof b !== "number" || !Number.isInteger(b) || b < 0 || b > 255) {
2536
+ throw new CofheError({
2537
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
2538
+ message: "decrypt response field <decrypted> contained a non-byte value",
2539
+ context: {
2540
+ badElement: b,
2541
+ decrypted
2542
+ }
2543
+ });
2544
+ }
2545
+ hex += b.toString(16).padStart(2, "0");
2546
+ }
2547
+ return BigInt(`0x${hex}`);
2548
+ }
2549
+ function assertTnDecryptResponse(value) {
2550
+ if (value == null || typeof value !== "object") {
2551
+ throw new CofheError({
2552
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
2553
+ message: "decrypt response must be a JSON object",
2554
+ context: {
2555
+ value
2556
+ }
2557
+ });
2558
+ }
2559
+ const v = value;
2560
+ const decrypted = v.decrypted;
2561
+ const signature = v.signature;
2562
+ const encryptionType = v.encryption_type;
2563
+ const errorMessage = v.error_message;
2564
+ if (!Array.isArray(decrypted)) {
2565
+ throw new CofheError({
2566
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
2567
+ message: "decrypt response missing <decrypted> byte array",
2568
+ context: { decryptResponse: value }
2569
+ });
2570
+ }
2571
+ if (typeof signature !== "string") {
2572
+ throw new CofheError({
2573
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
2574
+ message: "decrypt response missing <signature> string",
2575
+ context: { decryptResponse: value }
2576
+ });
2577
+ }
2578
+ if (typeof encryptionType !== "number") {
2579
+ throw new CofheError({
2580
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
2581
+ message: "decrypt response missing <encryption_type> number",
2582
+ context: { decryptResponse: value }
2583
+ });
2584
+ }
2585
+ if (!(typeof errorMessage === "string" || errorMessage === null)) {
2586
+ throw new CofheError({
2587
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
2588
+ message: "decrypt response field <error_message> must be string or null",
2589
+ context: { decryptResponse: value }
2590
+ });
2591
+ }
2592
+ return {
2593
+ decrypted,
2594
+ signature,
2595
+ encryption_type: encryptionType,
2596
+ error_message: errorMessage
2597
+ };
2598
+ }
2599
+ async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
2600
+ const body = {
2601
+ ct_tempkey: ctHash.toString(16).padStart(64, "0"),
2602
+ host_chain_id: chainId
2603
+ };
2604
+ if (permission) {
2605
+ body.permit = permission;
2606
+ }
2607
+ let response;
2608
+ try {
2609
+ response = await fetch(`${thresholdNetworkUrl}/decrypt`, {
2610
+ method: "POST",
2611
+ headers: {
2612
+ "Content-Type": "application/json"
2613
+ },
2614
+ body: JSON.stringify(body)
2615
+ });
2616
+ } catch (e) {
2617
+ throw new CofheError({
2618
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
2619
+ message: `decrypt request failed`,
2620
+ hint: "Ensure the threshold network URL is valid and reachable.",
2621
+ cause: e instanceof Error ? e : void 0,
2622
+ context: {
2623
+ thresholdNetworkUrl,
2624
+ body
2625
+ }
2626
+ });
2627
+ }
2628
+ const responseText = await response.text();
2629
+ if (!response.ok) {
2630
+ let errorMessage = response.statusText || `HTTP ${response.status}`;
2631
+ try {
2632
+ const errorBody = JSON.parse(responseText);
2633
+ const maybeMessage = errorBody.error_message || errorBody.message;
2634
+ if (typeof maybeMessage === "string" && maybeMessage.length > 0)
2635
+ errorMessage = maybeMessage;
2636
+ } catch {
2637
+ const trimmed = responseText.trim();
2638
+ if (trimmed.length > 0)
2639
+ errorMessage = trimmed;
2640
+ }
2641
+ throw new CofheError({
2642
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
2643
+ message: `decrypt request failed: ${errorMessage}`,
2644
+ hint: "Check the threshold network URL and request parameters.",
2645
+ context: {
2646
+ thresholdNetworkUrl,
2647
+ status: response.status,
2648
+ statusText: response.statusText,
2649
+ body,
2650
+ responseText
2651
+ }
2652
+ });
2653
+ }
2654
+ let rawJson;
2655
+ try {
2656
+ rawJson = JSON.parse(responseText);
2657
+ } catch (e) {
2658
+ throw new CofheError({
2659
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
2660
+ message: `Failed to parse decrypt response`,
2661
+ cause: e instanceof Error ? e : void 0,
2662
+ context: {
2663
+ thresholdNetworkUrl,
2664
+ body,
2665
+ responseText
2666
+ }
2667
+ });
2668
+ }
2669
+ const decryptResponse = assertTnDecryptResponse(rawJson);
2670
+ if (decryptResponse.error_message) {
2671
+ throw new CofheError({
2672
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
2673
+ message: `decrypt request failed: ${decryptResponse.error_message}`,
2674
+ context: {
2675
+ thresholdNetworkUrl,
2676
+ body,
2677
+ decryptResponse
2678
+ }
2679
+ });
2680
+ }
2681
+ const decryptedValue = parseDecryptedBytesToBigInt(decryptResponse.decrypted);
2682
+ const signature = normalizeSignature(decryptResponse.signature);
2683
+ return { decryptedValue, signature };
2684
+ }
2685
+
2686
+ // core/decrypt/decryptForTxBuilder.ts
2687
+ var DecryptForTxBuilder = class extends BaseBuilder {
2688
+ ctHash;
2689
+ permitHash;
2690
+ permit;
2691
+ permitSelection = "unset";
2692
+ constructor(params) {
2693
+ super({
2694
+ config: params.config,
2695
+ publicClient: params.publicClient,
2696
+ walletClient: params.walletClient,
2697
+ chainId: params.chainId,
2698
+ account: params.account,
2699
+ requireConnected: params.requireConnected
2700
+ });
2701
+ this.ctHash = params.ctHash;
2702
+ }
2703
+ setChainId(chainId) {
2704
+ this.chainId = chainId;
2705
+ return this;
2706
+ }
2707
+ getChainId() {
2708
+ return this.chainId;
2709
+ }
2710
+ setAccount(account) {
2711
+ this.account = account;
2712
+ return this;
2713
+ }
2714
+ getAccount() {
2715
+ return this.account;
2716
+ }
2717
+ withPermit(permitOrPermitHash) {
2718
+ if (this.permitSelection === "with-permit") {
2719
+ throw new CofheError({
2720
+ code: "INTERNAL_ERROR" /* InternalError */,
2721
+ message: "decryptForTx: withPermit() can only be selected once.",
2722
+ hint: "Choose the permit mode once. If you need a different permit, start a new decryptForTx() builder chain."
2723
+ });
2724
+ }
2725
+ if (this.permitSelection === "without-permit") {
2726
+ throw new CofheError({
2727
+ code: "INTERNAL_ERROR" /* InternalError */,
2728
+ message: "decryptForTx: cannot call withPermit() after withoutPermit() has been selected.",
2729
+ hint: "Choose exactly one permit mode: either call .withPermit(...) or .withoutPermit(), but not both."
2730
+ });
2731
+ }
2732
+ this.permitSelection = "with-permit";
2733
+ if (typeof permitOrPermitHash === "string") {
2734
+ this.permitHash = permitOrPermitHash;
2735
+ this.permit = void 0;
2736
+ } else if (permitOrPermitHash === void 0) {
2737
+ this.permitHash = void 0;
2738
+ this.permit = void 0;
2739
+ } else {
2740
+ this.permit = permitOrPermitHash;
2741
+ this.permitHash = void 0;
2742
+ }
2743
+ return this;
2744
+ }
2745
+ /**
2746
+ * Select "no permit" mode.
2747
+ *
2748
+ * This uses global allowance (no permit required) and sends an empty permission payload to `/decrypt`.
2749
+ */
2750
+ withoutPermit() {
2751
+ if (this.permitSelection === "without-permit") {
2752
+ throw new CofheError({
2753
+ code: "INTERNAL_ERROR" /* InternalError */,
2754
+ message: "decryptForTx: withoutPermit() can only be selected once.",
2755
+ hint: "Choose the permit mode once. If you need a different mode, start a new decryptForTx() builder chain."
2756
+ });
2757
+ }
2758
+ if (this.permitSelection === "with-permit") {
2759
+ throw new CofheError({
2760
+ code: "INTERNAL_ERROR" /* InternalError */,
2761
+ message: "decryptForTx: cannot call withoutPermit() after withPermit() has been selected.",
2762
+ hint: "Choose exactly one permit mode: either call .withPermit(...) or .withoutPermit(), but not both."
2763
+ });
2764
+ }
2765
+ this.permitSelection = "without-permit";
2766
+ this.permitHash = void 0;
2767
+ this.permit = void 0;
2768
+ return this;
2769
+ }
2770
+ getPermit() {
2771
+ return this.permit;
2772
+ }
2773
+ getPermitHash() {
2774
+ return this.permitHash;
2775
+ }
2776
+ async getThresholdNetworkUrl() {
2777
+ this.assertChainId();
2778
+ return getThresholdNetworkUrlOrThrow(this.config, this.chainId);
2779
+ }
2780
+ async getResolvedPermit() {
2781
+ if (this.permitSelection === "unset") {
2782
+ throw new CofheError({
2783
+ code: "INTERNAL_ERROR" /* InternalError */,
2784
+ message: "decryptForTx: missing permit selection; call withPermit(...) or withoutPermit() before execute().",
2785
+ hint: "Call .withPermit() to use the active permit, or .withoutPermit() for global allowance."
2786
+ });
2787
+ }
2788
+ if (this.permitSelection === "without-permit") {
2789
+ return null;
2790
+ }
2791
+ if (this.permit)
2792
+ return this.permit;
2793
+ this.assertChainId();
2794
+ this.assertAccount();
2795
+ if (this.permitHash) {
2796
+ const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
2797
+ if (!permit2) {
2798
+ throw new CofheError({
2799
+ code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
2800
+ message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
2801
+ hint: "Ensure the permit exists and is valid.",
2802
+ context: {
2803
+ chainId: this.chainId,
2804
+ account: this.account,
2805
+ permitHash: this.permitHash
2806
+ }
2807
+ });
2808
+ }
2809
+ return permit2;
2810
+ }
2811
+ const permit = await permits.getActivePermit(this.chainId, this.account);
2812
+ if (!permit) {
2813
+ throw new CofheError({
2814
+ code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
2815
+ message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
2816
+ hint: "Create a permit (e.g. client.permits.createSelf(...)) and/or set it active (client.permits.selectActivePermit(hash)).",
2817
+ context: {
2818
+ chainId: this.chainId,
2819
+ account: this.account
2820
+ }
2821
+ });
2822
+ }
2823
+ return permit;
2824
+ }
2825
+ /**
2826
+ * On hardhat, interact with MockThresholdNetwork contract
2827
+ */
2828
+ async mocksDecryptForTx(permit) {
2829
+ this.assertPublicClient();
2830
+ const delay = this.config.mocks.decryptDelay;
2831
+ const result = await cofheMocksDecryptForTx(this.ctHash, 0, permit, this.publicClient, delay);
2832
+ return result;
2833
+ }
2834
+ /**
2835
+ * In the production context, perform a true decryption with the CoFHE coprocessor.
2836
+ */
2837
+ async productionDecryptForTx(permit) {
2838
+ this.assertChainId();
2839
+ this.assertPublicClient();
2840
+ const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
2841
+ const permission = permit ? PermitUtils.getPermission(permit, true) : null;
2842
+ const { decryptedValue, signature } = await tnDecrypt(this.ctHash, this.chainId, permission, thresholdNetworkUrl);
2843
+ return {
2844
+ ctHash: this.ctHash,
2845
+ decryptedValue,
2846
+ signature
2847
+ };
2848
+ }
2849
+ /**
2850
+ * Final step of the decryptForTx process. MUST BE CALLED LAST IN THE CHAIN.
2851
+ *
2852
+ * You must explicitly choose one permit mode before calling `execute()`:
2853
+ * - `withPermit(permit)` / `withPermit(permitHash)` / `withPermit()` (active permit)
2854
+ * - `withoutPermit()` (global allowance)
2855
+ */
2856
+ async execute() {
2857
+ const permit = await this.getResolvedPermit();
2858
+ if (permit !== null) {
2859
+ PermitUtils.validate(permit);
2860
+ PermitUtils.isValid(permit);
2861
+ const chainId = permit._signedDomain.chainId;
2862
+ if (chainId === hardhat$1.id) {
2863
+ return await this.mocksDecryptForTx(permit);
2864
+ } else {
2865
+ return await this.productionDecryptForTx(permit);
2866
+ }
2867
+ } else {
2868
+ if (!this.chainId) {
2869
+ this.assertPublicClient();
2870
+ this.chainId = await getPublicClientChainID(this.publicClient);
2871
+ }
2872
+ this.assertChainId();
2873
+ if (this.chainId === hardhat$1.id) {
2874
+ return await this.mocksDecryptForTx(null);
2875
+ } else {
2876
+ return await this.productionDecryptForTx(null);
2877
+ }
2878
+ }
2879
+ }
2880
+ };
2881
+
2318
2882
  // core/client.ts
2319
2883
  var InitialConnectStore = {
2320
2884
  connected: false,
@@ -2325,9 +2889,10 @@ var InitialConnectStore = {
2325
2889
  publicClient: void 0,
2326
2890
  walletClient: void 0
2327
2891
  };
2328
- function createCofhesdkClientBase(opts) {
2892
+ function createCofheClientBase(opts) {
2329
2893
  const keysStorage = createKeysStore(opts.config.fheKeyStorage);
2330
2894
  const connectStore = createStore(() => InitialConnectStore);
2895
+ let connectAttemptId = 0;
2331
2896
  const updateConnectState = (partial) => {
2332
2897
  connectStore.setState((state) => ({ ...state, ...partial }));
2333
2898
  };
@@ -2335,7 +2900,7 @@ function createCofhesdkClientBase(opts) {
2335
2900
  const state = connectStore.getState();
2336
2901
  const notConnected = !state.connected || !state.account || !state.chainId || !state.publicClient || !state.walletClient;
2337
2902
  if (notConnected) {
2338
- throw new CofhesdkError({
2903
+ throw new CofheError({
2339
2904
  code: "NOT_CONNECTED" /* NotConnected */,
2340
2905
  message: "Client must be connected, account and chainId must be initialized",
2341
2906
  hint: "Ensure client.connect() has been called and awaited.",
@@ -2353,6 +2918,8 @@ function createCofhesdkClientBase(opts) {
2353
2918
  const state = connectStore.getState();
2354
2919
  if (state.connected && state.publicClient === publicClient && state.walletClient === walletClient)
2355
2920
  return;
2921
+ connectAttemptId += 1;
2922
+ const localAttemptId = connectAttemptId;
2356
2923
  updateConnectState({
2357
2924
  ...InitialConnectStore,
2358
2925
  connecting: true
@@ -2360,6 +2927,8 @@ function createCofhesdkClientBase(opts) {
2360
2927
  try {
2361
2928
  const chainId = await getPublicClientChainID(publicClient);
2362
2929
  const account = await getWalletClientAccount(walletClient);
2930
+ if (localAttemptId !== connectAttemptId)
2931
+ return;
2363
2932
  updateConnectState({
2364
2933
  connected: true,
2365
2934
  connecting: false,
@@ -2370,6 +2939,8 @@ function createCofhesdkClientBase(opts) {
2370
2939
  walletClient
2371
2940
  });
2372
2941
  } catch (e) {
2942
+ if (localAttemptId !== connectAttemptId)
2943
+ return;
2373
2944
  updateConnectState({
2374
2945
  ...InitialConnectStore,
2375
2946
  connectError: e
@@ -2377,6 +2948,10 @@ function createCofhesdkClientBase(opts) {
2377
2948
  throw e;
2378
2949
  }
2379
2950
  }
2951
+ function disconnect() {
2952
+ connectAttemptId += 1;
2953
+ updateConnectState({ ...InitialConnectStore });
2954
+ }
2380
2955
  function encryptInputs(inputs) {
2381
2956
  const state = connectStore.getState();
2382
2957
  return new EncryptInputsBuilder({
@@ -2396,16 +2971,28 @@ function createCofhesdkClientBase(opts) {
2396
2971
  requireConnected: _requireConnected
2397
2972
  });
2398
2973
  }
2399
- function decryptHandle(ctHash, utype) {
2974
+ function decryptForView(ctHash, utype) {
2400
2975
  const state = connectStore.getState();
2401
- return new DecryptHandlesBuilder({
2976
+ return new DecryptForViewBuilder({
2402
2977
  ctHash,
2403
2978
  utype,
2404
- chainId: state.chainId ?? void 0,
2405
- account: state.account ?? void 0,
2979
+ chainId: state.chainId,
2980
+ account: state.account,
2406
2981
  config: opts.config,
2407
- publicClient: state.publicClient ?? void 0,
2408
- walletClient: state.walletClient ?? void 0,
2982
+ publicClient: state.publicClient,
2983
+ walletClient: state.walletClient,
2984
+ requireConnected: _requireConnected
2985
+ });
2986
+ }
2987
+ function decryptForTx(ctHash) {
2988
+ const state = connectStore.getState();
2989
+ return new DecryptForTxBuilder({
2990
+ ctHash,
2991
+ chainId: state.chainId,
2992
+ account: state.account,
2993
+ config: opts.config,
2994
+ publicClient: state.publicClient,
2995
+ walletClient: state.walletClient,
2409
2996
  requireConnected: _requireConnected
2410
2997
  });
2411
2998
  }
@@ -2414,7 +3001,7 @@ function createCofhesdkClientBase(opts) {
2414
3001
  const _chainId = chainId ?? state.chainId;
2415
3002
  const _account = account ?? state.account;
2416
3003
  if (_chainId == null || _account == null) {
2417
- throw new CofhesdkError({
3004
+ throw new CofheError({
2418
3005
  code: "NOT_CONNECTED" /* NotConnected */,
2419
3006
  message: "ChainId or account not available.",
2420
3007
  hint: "Ensure client.connect() has been called, or provide chainId and account explicitly.",
@@ -2481,9 +3068,9 @@ function createCofhesdkClientBase(opts) {
2481
3068
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
2482
3069
  return permits.selectActivePermit(_chainId, _account, hash);
2483
3070
  },
2484
- removePermit: async (hash, chainId, account, force) => {
3071
+ removePermit: async (hash, chainId, account) => {
2485
3072
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
2486
- return permits.removePermit(_chainId, _account, hash, force);
3073
+ return permits.removePermit(_chainId, _account, hash);
2487
3074
  },
2488
3075
  removeActivePermit: async (chainId, account) => {
2489
3076
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
@@ -2499,6 +3086,9 @@ function createCofhesdkClientBase(opts) {
2499
3086
  getSnapshot: connectStore.getState,
2500
3087
  subscribe: connectStore.subscribe,
2501
3088
  // flags (read-only: reflect snapshot)
3089
+ get connection() {
3090
+ return connectStore.getState();
3091
+ },
2502
3092
  get connected() {
2503
3093
  return connectStore.getState().connected;
2504
3094
  },
@@ -2508,8 +3098,14 @@ function createCofhesdkClientBase(opts) {
2508
3098
  // config & platform-specific (read-only)
2509
3099
  config: opts.config,
2510
3100
  connect,
3101
+ disconnect,
2511
3102
  encryptInputs,
2512
- decryptHandle,
3103
+ decryptForView,
3104
+ /**
3105
+ * @deprecated Use `decryptForView` instead. Kept for backward compatibility.
3106
+ */
3107
+ decryptHandle: decryptForView,
3108
+ decryptForTx,
2513
3109
  permits: clientPermits
2514
3110
  // Add SDK-specific methods below that require connection
2515
3111
  // Example:
@@ -2520,4 +3116,4 @@ function createCofhesdkClientBase(opts) {
2520
3116
  };
2521
3117
  }
2522
3118
 
2523
- export { CofhesdkError, CofhesdkErrorCode, DecryptHandlesBuilder, EncryptInputsBuilder, EncryptStep, Encryptable, FheAllUTypes, FheTypes, FheUintUTypes, InitialConnectStore, MOCKS_ZK_VERIFIER_SIGNER_ADDRESS, assertCorrectEncryptedItemInput, createCofhesdkClientBase, createCofhesdkConfigBase, createKeysStore, fetchKeys, fheTypeToString, getCofhesdkConfigItem, isCofhesdkError, isEncryptableItem, isLastEncryptionStep, zkProveWithWorker };
3119
+ export { CofheError, CofheErrorCode, DecryptForTxBuilder, DecryptForViewBuilder, EncryptInputsBuilder, EncryptStep, Encryptable, FheAllUTypes, FheTypes, FheUintUTypes, InitialConnectStore, assertCorrectEncryptedItemInput, createCofheClientBase, createCofheConfigBase, createKeysStore, fetchKeys, fheTypeToString, getCofheConfigItem, isCofheError, isEncryptableItem, isLastEncryptionStep, zkProveWithWorker };