@cofhe/sdk 0.2.1 → 0.3.1

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 (54) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/core/baseBuilder.ts +18 -18
  3. package/core/client.test.ts +58 -55
  4. package/core/client.ts +50 -30
  5. package/core/clientTypes.ts +21 -17
  6. package/core/config.test.ts +32 -33
  7. package/core/config.ts +47 -48
  8. package/core/consts.ts +6 -2
  9. package/core/decrypt/{MockQueryDecrypterAbi.ts → MockThresholdNetworkAbi.ts} +71 -21
  10. package/core/decrypt/cofheMocksDecryptForTx.ts +142 -0
  11. package/core/decrypt/{cofheMocksSealOutput.ts → cofheMocksDecryptForView.ts} +12 -12
  12. package/core/decrypt/decryptForTxBuilder.ts +340 -0
  13. package/core/decrypt/{decryptHandleBuilder.ts → decryptForViewBuilder.ts} +75 -42
  14. package/core/decrypt/tnDecrypt.ts +232 -0
  15. package/core/decrypt/tnSealOutputV1.ts +5 -5
  16. package/core/decrypt/tnSealOutputV2.ts +27 -27
  17. package/core/encrypt/cofheMocksZkVerifySign.ts +15 -15
  18. package/core/encrypt/encryptInputsBuilder.test.ts +57 -61
  19. package/core/encrypt/encryptInputsBuilder.ts +65 -42
  20. package/core/encrypt/zkPackProveVerify.ts +11 -11
  21. package/core/error.ts +18 -18
  22. package/core/fetchKeys.test.ts +3 -3
  23. package/core/fetchKeys.ts +3 -3
  24. package/core/index.ts +14 -11
  25. package/core/utils.ts +10 -10
  26. package/dist/{chunk-I5WFEYXX.js → chunk-2TPSCOW3.js} +791 -209
  27. package/dist/{chunk-R3B5TMVX.js → chunk-NWDKXBIP.js} +3 -2
  28. package/dist/{clientTypes-RqkgkV2i.d.ts → clientTypes-6aTZPQ_4.d.ts} +204 -85
  29. package/dist/{clientTypes-e4filDzK.d.cts → clientTypes-Bhq7pCSA.d.cts} +204 -85
  30. package/dist/core.cjs +799 -214
  31. package/dist/core.d.cts +25 -23
  32. package/dist/core.d.ts +25 -23
  33. package/dist/core.js +2 -2
  34. package/dist/node.cjs +748 -165
  35. package/dist/node.d.cts +10 -10
  36. package/dist/node.d.ts +10 -10
  37. package/dist/node.js +7 -7
  38. package/dist/permits.js +1 -1
  39. package/dist/web.cjs +751 -168
  40. package/dist/web.d.cts +11 -11
  41. package/dist/web.d.ts +11 -11
  42. package/dist/web.js +9 -9
  43. package/node/client.test.ts +34 -34
  44. package/node/config.test.ts +11 -11
  45. package/node/encryptInputs.test.ts +29 -29
  46. package/node/index.ts +15 -15
  47. package/package.json +3 -3
  48. package/web/client.web.test.ts +34 -34
  49. package/web/config.web.test.ts +11 -11
  50. package/web/encryptInputs.web.test.ts +29 -29
  51. package/web/index.ts +19 -19
  52. package/web/worker.builder.web.test.ts +28 -28
  53. package/web/worker.config.web.test.ts +47 -47
  54. package/web/worker.output.web.test.ts +10 -10
package/dist/web.cjs CHANGED
@@ -38,7 +38,7 @@ var init__default = /*#__PURE__*/_interopDefault(init);
38
38
  // core/client.ts
39
39
 
40
40
  // core/error.ts
41
- var CofhesdkError = class _CofhesdkError extends Error {
41
+ var CofheError = class _CofheError extends Error {
42
42
  code;
43
43
  cause;
44
44
  hint;
@@ -46,25 +46,25 @@ var CofhesdkError = class _CofhesdkError extends Error {
46
46
  constructor({ code, message, cause, hint, context }) {
47
47
  const fullMessage = cause ? `${message} | Caused by: ${cause.message}` : message;
48
48
  super(fullMessage);
49
- this.name = "CofhesdkError";
49
+ this.name = "CofheError";
50
50
  this.code = code;
51
51
  this.cause = cause;
52
52
  this.hint = hint;
53
53
  this.context = context;
54
54
  if (Error.captureStackTrace) {
55
- Error.captureStackTrace(this, _CofhesdkError);
55
+ Error.captureStackTrace(this, _CofheError);
56
56
  }
57
57
  }
58
58
  /**
59
- * Creates a CofhesdkError from an unknown error
60
- * If the error is a CofhesdkError, it is returned unchanged, else a new CofhesdkError is created
61
- * If a wrapperError is provided, it is used to create the new CofhesdkError, else a default is used
59
+ * Creates a CofheError from an unknown error
60
+ * If the error is a CofheError, it is returned unchanged, else a new CofheError is created
61
+ * If a wrapperError is provided, it is used to create the new CofheError, else a default is used
62
62
  */
63
63
  static fromError(error, wrapperError) {
64
- if (isCofhesdkError(error))
64
+ if (isCofheError(error))
65
65
  return error;
66
66
  const cause = error instanceof Error ? error : new Error(`${error}`);
67
- return new _CofhesdkError({
67
+ return new _CofheError({
68
68
  code: wrapperError?.code ?? "INTERNAL_ERROR" /* InternalError */,
69
69
  message: wrapperError?.message ?? "An internal error occurred",
70
70
  hint: wrapperError?.hint,
@@ -124,7 +124,7 @@ var bigintSafeJsonStringify = (value) => {
124
124
  return value2;
125
125
  });
126
126
  };
127
- var isCofhesdkError = (error) => error instanceof CofhesdkError;
127
+ var isCofheError = (error) => error instanceof CofheError;
128
128
 
129
129
  // core/types.ts
130
130
  var FheUintUTypes = [
@@ -168,14 +168,14 @@ async function getPublicClientChainID(publicClient) {
168
168
  try {
169
169
  chainId = publicClient.chain?.id ?? await publicClient.getChainId();
170
170
  } catch (e) {
171
- throw new CofhesdkError({
171
+ throw new CofheError({
172
172
  code: "PUBLIC_WALLET_GET_CHAIN_ID_FAILED" /* PublicWalletGetChainIdFailed */,
173
173
  message: "getting chain ID from public client failed",
174
174
  cause: e instanceof Error ? e : void 0
175
175
  });
176
176
  }
177
177
  if (chainId === null) {
178
- throw new CofhesdkError({
178
+ throw new CofheError({
179
179
  code: "PUBLIC_WALLET_GET_CHAIN_ID_FAILED" /* PublicWalletGetChainIdFailed */,
180
180
  message: "chain ID from public client is null"
181
181
  });
@@ -190,14 +190,14 @@ async function getWalletClientAccount(walletClient) {
190
190
  address = (await walletClient.getAddresses())?.[0];
191
191
  }
192
192
  } catch (e) {
193
- throw new CofhesdkError({
193
+ throw new CofheError({
194
194
  code: "PUBLIC_WALLET_GET_ADDRESSES_FAILED" /* PublicWalletGetAddressesFailed */,
195
195
  message: "getting address from wallet client failed",
196
196
  cause: e instanceof Error ? e : void 0
197
197
  });
198
198
  }
199
199
  if (!address) {
200
- throw new CofhesdkError({
200
+ throw new CofheError({
201
201
  code: "PUBLIC_WALLET_GET_ADDRESSES_FAILED" /* PublicWalletGetAddressesFailed */,
202
202
  message: "address from wallet client is null"
203
203
  });
@@ -301,7 +301,7 @@ var zkPack = (items, builder) => {
301
301
  break;
302
302
  }
303
303
  default: {
304
- throw new CofhesdkError({
304
+ throw new CofheError({
305
305
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
306
306
  message: `Invalid utype: ${item.utype}`,
307
307
  hint: `Ensure that the utype is valid, using the Encryptable type, for example: Encryptable.uint128(100n)`,
@@ -313,7 +313,7 @@ var zkPack = (items, builder) => {
313
313
  }
314
314
  }
315
315
  if (totalBits > MAX_ENCRYPTABLE_BITS) {
316
- throw new CofhesdkError({
316
+ throw new CofheError({
317
317
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
318
318
  message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
319
319
  hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
@@ -377,14 +377,14 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
377
377
  });
378
378
  if (!response.ok) {
379
379
  const errorBody = await response.text();
380
- throw new CofhesdkError({
380
+ throw new CofheError({
381
381
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
382
382
  message: `HTTP error! ZK proof verification failed - ${errorBody}`
383
383
  });
384
384
  }
385
385
  const json = await response.json();
386
386
  if (json.status !== "success") {
387
- throw new CofhesdkError({
387
+ throw new CofheError({
388
388
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
389
389
  message: `ZK proof verification response malformed - ${json.error}`
390
390
  });
@@ -396,7 +396,7 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
396
396
  };
397
397
  });
398
398
  } catch (e) {
399
- throw new CofhesdkError({
399
+ throw new CofheError({
400
400
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
401
401
  message: `ZK proof verification failed`,
402
402
  cause: e instanceof Error ? e : void 0
@@ -518,8 +518,9 @@ var MockZkVerifierAbi = [
518
518
  // core/consts.ts
519
519
  var TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
520
520
  var MOCKS_ZK_VERIFIER_ADDRESS = "0x0000000000000000000000000000000000005001";
521
- var MOCKS_QUERY_DECRYPTER_ADDRESS = "0x0000000000000000000000000000000000005002";
521
+ var MOCKS_THRESHOLD_NETWORK_ADDRESS = "0x0000000000000000000000000000000000005002";
522
522
  var MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = "0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512";
523
+ var MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d";
523
524
 
524
525
  // core/encrypt/cofheMocksZkVerifySign.ts
525
526
  function createMockZkVerifierSigner() {
@@ -564,7 +565,7 @@ async function cofheMocksCheckEncryptableBits(items) {
564
565
  }
565
566
  }
566
567
  if (totalBits > MAX_ENCRYPTABLE_BITS) {
567
- throw new CofhesdkError({
568
+ throw new CofheError({
568
569
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
569
570
  message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
570
571
  hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
@@ -593,7 +594,7 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
593
594
  args: calcCtHashesArgs
594
595
  });
595
596
  } catch (err) {
596
- throw new CofhesdkError({
597
+ throw new CofheError({
597
598
  code: "ZK_MOCKS_CALC_CT_HASHES_FAILED" /* ZkMocksCalcCtHashesFailed */,
598
599
  message: `mockZkVerifySign calcCtHashes failed while calling zkVerifyCalcCtHashesPacked`,
599
600
  cause: err instanceof Error ? err : void 0,
@@ -608,7 +609,7 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
608
609
  });
609
610
  }
610
611
  if (ctHashes.length !== items.length) {
611
- throw new CofhesdkError({
612
+ throw new CofheError({
612
613
  code: "ZK_MOCKS_CALC_CT_HASHES_FAILED" /* ZkMocksCalcCtHashesFailed */,
613
614
  message: `mockZkVerifySign calcCtHashes returned incorrect number of ctHashes`,
614
615
  context: {
@@ -639,7 +640,7 @@ async function insertCtHashes(items, walletClient) {
639
640
  account
640
641
  });
641
642
  } catch (err) {
642
- throw new CofhesdkError({
643
+ throw new CofheError({
643
644
  code: "ZK_MOCKS_INSERT_CT_HASHES_FAILED" /* ZkMocksInsertCtHashesFailed */,
644
645
  message: `mockZkVerifySign insertPackedCtHashes failed while calling insertPackedCtHashes`,
645
646
  cause: err instanceof Error ? err : void 0,
@@ -657,7 +658,7 @@ async function createProofSignatures(items, securityZone) {
657
658
  try {
658
659
  encInputSignerClient = createMockZkVerifierSigner();
659
660
  } catch (err) {
660
- throw new CofhesdkError({
661
+ throw new CofheError({
661
662
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
662
663
  message: `mockZkVerifySign createProofSignatures failed while creating wallet client`,
663
664
  cause: err instanceof Error ? err : void 0,
@@ -678,7 +679,7 @@ async function createProofSignatures(items, securityZone) {
678
679
  signatures.push(signature);
679
680
  }
680
681
  } catch (err) {
681
- throw new CofhesdkError({
682
+ throw new CofheError({
682
683
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
683
684
  message: `mockZkVerifySign createProofSignatures failed while calling signMessage`,
684
685
  cause: err instanceof Error ? err : void 0,
@@ -689,7 +690,7 @@ async function createProofSignatures(items, securityZone) {
689
690
  });
690
691
  }
691
692
  if (signatures.length !== items.length) {
692
- throw new CofhesdkError({
693
+ throw new CofheError({
693
694
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
694
695
  message: `mockZkVerifySign createProofSignatures returned incorrect number of signatures`,
695
696
  context: {
@@ -746,13 +747,11 @@ var hardhat2 = defineChain({
746
747
  thresholdNetworkUrl: "http://127.0.0.1:3000",
747
748
  environment: "MOCK"
748
749
  });
749
- var CofhesdkConfigSchema = zod.z.object({
750
+ var CofheConfigSchema = zod.z.object({
750
751
  /** Environment that the SDK is running in */
751
752
  environment: zod.z.enum(["node", "hardhat", "web", "react"]).optional().default("node"),
752
753
  /** List of supported chain configurations */
753
754
  supportedChains: zod.z.array(zod.z.custom()),
754
- /** How permits are generated */
755
- permitGeneration: zod.z.enum(["ON_CONNECT", "ON_DECRYPT_HANDLES", "MANUAL"]).optional().default("ON_CONNECT"),
756
755
  /** Default permit expiration in seconds, default is 30 days */
757
756
  defaultPermitExpiration: zod.z.number().optional().default(60 * 60 * 24 * 30),
758
757
  /** Storage method for fhe keys (defaults to indexedDB on web, filesystem on node) */
@@ -771,24 +770,25 @@ var CofhesdkConfigSchema = zod.z.object({
771
770
  useWorkers: zod.z.boolean().optional().default(true),
772
771
  /** Mocks configs */
773
772
  mocks: zod.z.object({
774
- sealOutputDelay: zod.z.number().optional().default(0)
775
- }).optional().default({ sealOutputDelay: 0 }),
773
+ decryptDelay: zod.z.number().optional().default(0),
774
+ 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])
775
+ }).optional().default({ decryptDelay: 0, encryptDelay: [100, 100, 100, 500, 500] }),
776
776
  /** Internal configuration */
777
777
  _internal: zod.z.object({
778
778
  zkvWalletClient: zod.z.any().optional()
779
779
  }).optional()
780
780
  });
781
- function createCofhesdkConfigBase(config) {
782
- const result = CofhesdkConfigSchema.safeParse(config);
781
+ function createCofheConfigBase(config) {
782
+ const result = CofheConfigSchema.safeParse(config);
783
783
  if (!result.success) {
784
- throw new Error(`Invalid cofhesdk configuration: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
784
+ throw new Error(`Invalid cofhe configuration: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
785
785
  }
786
786
  return result.data;
787
787
  }
788
788
  function getSupportedChainOrThrow(config, chainId) {
789
789
  const supportedChain = config.supportedChains.find((chain) => chain.id === chainId);
790
790
  if (!supportedChain) {
791
- throw new CofhesdkError({
791
+ throw new CofheError({
792
792
  code: "UNSUPPORTED_CHAIN" /* UnsupportedChain */,
793
793
  message: `Config does not support chain <${chainId}>`,
794
794
  hint: "Ensure config passed to client has been created with this chain in the config.supportedChains array.",
@@ -804,7 +804,7 @@ function getCoFheUrlOrThrow(config, chainId) {
804
804
  const supportedChain = getSupportedChainOrThrow(config, chainId);
805
805
  const url = supportedChain.coFheUrl;
806
806
  if (!url) {
807
- throw new CofhesdkError({
807
+ throw new CofheError({
808
808
  code: "MISSING_CONFIG" /* MissingConfig */,
809
809
  message: `CoFHE URL is not configured for chain <${chainId}>`,
810
810
  hint: "Ensure this chain config includes a coFheUrl property.",
@@ -817,7 +817,7 @@ function getZkVerifierUrlOrThrow(config, chainId) {
817
817
  const supportedChain = getSupportedChainOrThrow(config, chainId);
818
818
  const url = supportedChain.verifierUrl;
819
819
  if (!url) {
820
- throw new CofhesdkError({
820
+ throw new CofheError({
821
821
  code: "ZK_VERIFIER_URL_UNINITIALIZED" /* ZkVerifierUrlUninitialized */,
822
822
  message: `ZK verifier URL is not configured for chain <${chainId}>`,
823
823
  hint: "Ensure this chain config includes a verifierUrl property.",
@@ -830,7 +830,7 @@ function getThresholdNetworkUrlOrThrow(config, chainId) {
830
830
  const supportedChain = getSupportedChainOrThrow(config, chainId);
831
831
  const url = supportedChain.thresholdNetworkUrl;
832
832
  if (!url) {
833
- throw new CofhesdkError({
833
+ throw new CofheError({
834
834
  code: "THRESHOLD_NETWORK_URL_UNINITIALIZED" /* ThresholdNetworkUrlUninitialized */,
835
835
  message: `Threshold network URL is not configured for chain <${chainId}>`,
836
836
  hint: "Ensure this chain config includes a thresholdNetworkUrl property.",
@@ -1042,7 +1042,7 @@ var BaseBuilder = class {
1042
1042
  account;
1043
1043
  constructor(params) {
1044
1044
  if (!params.config) {
1045
- throw new CofhesdkError({
1045
+ throw new CofheError({
1046
1046
  code: "MISSING_CONFIG" /* MissingConfig */,
1047
1047
  message: "Builder config is undefined",
1048
1048
  hint: "Ensure client has been created with a config.",
@@ -1060,12 +1060,12 @@ var BaseBuilder = class {
1060
1060
  }
1061
1061
  /**
1062
1062
  * Asserts that this.chainId is populated
1063
- * @throws {CofhesdkError} If chainId is not set
1063
+ * @throws {CofheError} If chainId is not set
1064
1064
  */
1065
1065
  assertChainId() {
1066
1066
  if (this.chainId)
1067
1067
  return;
1068
- throw new CofhesdkError({
1068
+ throw new CofheError({
1069
1069
  code: "CHAIN_ID_UNINITIALIZED" /* ChainIdUninitialized */,
1070
1070
  message: "Chain ID is not set",
1071
1071
  hint: "Ensure client.connect() has been called and awaited, or use setChainId(...) to set the chainId explicitly.",
@@ -1076,12 +1076,12 @@ var BaseBuilder = class {
1076
1076
  }
1077
1077
  /**
1078
1078
  * Asserts that this.account is populated
1079
- * @throws {CofhesdkError} If account is not set
1079
+ * @throws {CofheError} If account is not set
1080
1080
  */
1081
1081
  assertAccount() {
1082
1082
  if (this.account)
1083
1083
  return;
1084
- throw new CofhesdkError({
1084
+ throw new CofheError({
1085
1085
  code: "ACCOUNT_UNINITIALIZED" /* AccountUninitialized */,
1086
1086
  message: "Account is not set",
1087
1087
  hint: "Ensure client.connect() has been called and awaited, or use setAccount(...) to set the account explicitly.",
@@ -1092,12 +1092,12 @@ var BaseBuilder = class {
1092
1092
  }
1093
1093
  /**
1094
1094
  * Asserts that this.publicClient is populated
1095
- * @throws {CofhesdkError} If publicClient is not set
1095
+ * @throws {CofheError} If publicClient is not set
1096
1096
  */
1097
1097
  assertPublicClient() {
1098
1098
  if (this.publicClient)
1099
1099
  return;
1100
- throw new CofhesdkError({
1100
+ throw new CofheError({
1101
1101
  code: "MISSING_PUBLIC_CLIENT" /* MissingPublicClient */,
1102
1102
  message: "Public client not found",
1103
1103
  hint: "Ensure client.connect() has been called with a publicClient.",
@@ -1108,12 +1108,12 @@ var BaseBuilder = class {
1108
1108
  }
1109
1109
  /**
1110
1110
  * Asserts that this.walletClient is populated
1111
- * @throws {CofhesdkError} If walletClient is not set
1111
+ * @throws {CofheError} If walletClient is not set
1112
1112
  */
1113
1113
  assertWalletClient() {
1114
1114
  if (this.walletClient)
1115
1115
  return;
1116
- throw new CofhesdkError({
1116
+ throw new CofheError({
1117
1117
  code: "MISSING_WALLET_CLIENT" /* MissingWalletClient */,
1118
1118
  message: "Wallet client not found",
1119
1119
  hint: "Ensure client.connect() has been called with a walletClient.",
@@ -1158,7 +1158,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1158
1158
  this.securityZone = params.securityZone ?? 0;
1159
1159
  this.zkvWalletClient = params.zkvWalletClient;
1160
1160
  if (!params.tfhePublicKeyDeserializer) {
1161
- throw new CofhesdkError({
1161
+ throw new CofheError({
1162
1162
  code: "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER" /* MissingTfhePublicKeyDeserializer */,
1163
1163
  message: "EncryptInputsBuilder tfhePublicKeyDeserializer is undefined",
1164
1164
  hint: "Ensure client has been created with a tfhePublicKeyDeserializer.",
@@ -1169,7 +1169,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1169
1169
  }
1170
1170
  this.tfhePublicKeyDeserializer = params.tfhePublicKeyDeserializer;
1171
1171
  if (!params.compactPkeCrsDeserializer) {
1172
- throw new CofhesdkError({
1172
+ throw new CofheError({
1173
1173
  code: "MISSING_COMPACT_PKE_CRS_DESERIALIZER" /* MissingCompactPkeCrsDeserializer */,
1174
1174
  message: "EncryptInputsBuilder compactPkeCrsDeserializer is undefined",
1175
1175
  hint: "Ensure client has been created with a compactPkeCrsDeserializer.",
@@ -1180,7 +1180,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1180
1180
  }
1181
1181
  this.compactPkeCrsDeserializer = params.compactPkeCrsDeserializer;
1182
1182
  if (!params.zkBuilderAndCrsGenerator) {
1183
- throw new CofhesdkError({
1183
+ throw new CofheError({
1184
1184
  code: "MISSING_ZK_BUILDER_AND_CRS_GENERATOR" /* MissingZkBuilderAndCrsGenerator */,
1185
1185
  message: "EncryptInputsBuilder zkBuilderAndCrsGenerator is undefined",
1186
1186
  hint: "Ensure client has been created with a zkBuilderAndCrsGenerator.",
@@ -1204,7 +1204,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1204
1204
  * ```typescript
1205
1205
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1206
1206
  * .setAccount("0x123")
1207
- * .encrypt();
1207
+ * .execute();
1208
1208
  * ```
1209
1209
  *
1210
1210
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1225,7 +1225,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1225
1225
  * ```typescript
1226
1226
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1227
1227
  * .setChainId(11155111)
1228
- * .encrypt();
1228
+ * .execute();
1229
1229
  * ```
1230
1230
  *
1231
1231
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1246,7 +1246,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1246
1246
  * ```typescript
1247
1247
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1248
1248
  * .setSecurityZone(1)
1249
- * .encrypt();
1249
+ * .execute();
1250
1250
  * ```
1251
1251
  *
1252
1252
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1267,7 +1267,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1267
1267
  * ```typescript
1268
1268
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1269
1269
  * .setUseWorker(false)
1270
- * .encrypt();
1270
+ * .execute();
1271
1271
  * ```
1272
1272
  *
1273
1273
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1301,13 +1301,13 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1301
1301
  * Example:
1302
1302
  * ```typescript
1303
1303
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1304
- * .setStepCallback((step: EncryptStep) => console.log(step))
1305
- * .encrypt();
1304
+ * .onStep((step: EncryptStep) => console.log(step))
1305
+ * .execute();
1306
1306
  * ```
1307
1307
  *
1308
1308
  * @returns The EncryptInputsBuilder instance.
1309
1309
  */
1310
- setStepCallback(callback) {
1310
+ onStep(callback) {
1311
1311
  this.stepCallback = callback;
1312
1312
  return this;
1313
1313
  }
@@ -1330,7 +1330,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1330
1330
  this.stepCallback(step, { ...context, isStart: false, isEnd: true, duration });
1331
1331
  }
1332
1332
  /**
1333
- * zkVerifierUrl is included in the chains exported from cofhesdk/chains for use in CofhesdkConfig.supportedChains
1333
+ * zkVerifierUrl is included in the chains exported from @cofhe/sdk/chains for use in CofheConfig.supportedChains
1334
1334
  * Users should generally not set this manually.
1335
1335
  */
1336
1336
  async getZkVerifierUrl() {
@@ -1338,7 +1338,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1338
1338
  return getZkVerifierUrlOrThrow(this.config, this.chainId);
1339
1339
  }
1340
1340
  /**
1341
- * initTfhe is a platform-specific dependency injected into core/createCofhesdkClientBase by web/createCofhesdkClient and node/createCofhesdkClient
1341
+ * initTfhe is a platform-specific dependency injected into core/createCofheClientBase by web/createCofheClient and node/createCofheClient
1342
1342
  * web/ uses zama "tfhe"
1343
1343
  * node/ uses zama "node-tfhe"
1344
1344
  * Users should not set this manually.
@@ -1349,7 +1349,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1349
1349
  try {
1350
1350
  return await this.initTfhe();
1351
1351
  } catch (error) {
1352
- throw CofhesdkError.fromError(error, {
1352
+ throw CofheError.fromError(error, {
1353
1353
  code: "INIT_TFHE_FAILED" /* InitTfheFailed */,
1354
1354
  message: `Failed to initialize TFHE`,
1355
1355
  context: {
@@ -1368,7 +1368,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1368
1368
  try {
1369
1369
  await this.keysStorage?.rehydrateKeysStore();
1370
1370
  } catch (error) {
1371
- throw CofhesdkError.fromError(error, {
1371
+ throw CofheError.fromError(error, {
1372
1372
  code: "REHYDRATE_KEYS_STORE_FAILED" /* RehydrateKeysStoreFailed */,
1373
1373
  message: `Failed to rehydrate keys store`,
1374
1374
  context: {
@@ -1390,7 +1390,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1390
1390
  this.keysStorage
1391
1391
  );
1392
1392
  } catch (error) {
1393
- throw CofhesdkError.fromError(error, {
1393
+ throw CofheError.fromError(error, {
1394
1394
  code: "FETCH_KEYS_FAILED" /* FetchKeysFailed */,
1395
1395
  message: `Failed to fetch FHE key and CRS`,
1396
1396
  context: {
@@ -1403,7 +1403,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1403
1403
  });
1404
1404
  }
1405
1405
  if (!fheKey) {
1406
- throw new CofhesdkError({
1406
+ throw new CofheError({
1407
1407
  code: "MISSING_FHE_KEY" /* MissingFheKey */,
1408
1408
  message: `FHE key not found`,
1409
1409
  context: {
@@ -1413,7 +1413,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1413
1413
  });
1414
1414
  }
1415
1415
  if (!crs) {
1416
- throw new CofhesdkError({
1416
+ throw new CofheError({
1417
1417
  code: "MISSING_CRS" /* MissingCrs */,
1418
1418
  message: `CRS not found for chainId <${this.chainId}>`,
1419
1419
  context: {
@@ -1423,6 +1423,17 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1423
1423
  }
1424
1424
  return { fheKey, fheKeyFetchedFromCoFHE, crs, crsFetchedFromCoFHE };
1425
1425
  }
1426
+ /**
1427
+ * Resolves the encryptDelay config into an array of 5 per-step delays.
1428
+ * A single number is broadcast to all steps; a tuple is used as-is.
1429
+ */
1430
+ resolveEncryptDelays() {
1431
+ const encryptDelay = this.config?.mocks?.encryptDelay ?? [100, 100, 100, 500, 500];
1432
+ if (typeof encryptDelay === "number") {
1433
+ return [encryptDelay, encryptDelay, encryptDelay, encryptDelay, encryptDelay];
1434
+ }
1435
+ return encryptDelay;
1436
+ }
1426
1437
  /**
1427
1438
  * @dev Encrypt against the cofheMocks instead of CoFHE
1428
1439
  *
@@ -1430,25 +1441,35 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1430
1441
  * cofheMocksInsertPackedHashes - stores the ctHashes and their plaintext values for on-chain mocking of FHE operations.
1431
1442
  * cofheMocksZkCreateProofSignatures - creates signatures to be included in the encrypted inputs. The signers address is known and verified in the mock contracts.
1432
1443
  */
1433
- async mocksEncrypt() {
1444
+ async mocksExecute() {
1434
1445
  this.assertAccount();
1435
1446
  this.assertPublicClient();
1436
1447
  this.assertWalletClient();
1448
+ const [initTfheDelay, fetchKeysDelay, packDelay, proveDelay, verifyDelay] = this.resolveEncryptDelays();
1437
1449
  this.fireStepStart("initTfhe" /* InitTfhe */);
1438
- await sleep(100);
1439
- this.fireStepEnd("initTfhe" /* InitTfhe */, { tfheInitializationExecuted: false });
1450
+ await sleep(initTfheDelay);
1451
+ this.fireStepEnd("initTfhe" /* InitTfhe */, {
1452
+ tfheInitializationExecuted: false,
1453
+ isMocks: true,
1454
+ mockSleep: initTfheDelay
1455
+ });
1440
1456
  this.fireStepStart("fetchKeys" /* FetchKeys */);
1441
- await sleep(100);
1442
- this.fireStepEnd("fetchKeys" /* FetchKeys */, { fheKeyFetchedFromCoFHE: false, crsFetchedFromCoFHE: false });
1457
+ await sleep(fetchKeysDelay);
1458
+ this.fireStepEnd("fetchKeys" /* FetchKeys */, {
1459
+ fheKeyFetchedFromCoFHE: false,
1460
+ crsFetchedFromCoFHE: false,
1461
+ isMocks: true,
1462
+ mockSleep: fetchKeysDelay
1463
+ });
1443
1464
  this.fireStepStart("pack" /* Pack */);
1444
1465
  await cofheMocksCheckEncryptableBits(this.inputItems);
1445
- await sleep(100);
1446
- this.fireStepEnd("pack" /* Pack */);
1466
+ await sleep(packDelay);
1467
+ this.fireStepEnd("pack" /* Pack */, { isMocks: true, mockSleep: packDelay });
1447
1468
  this.fireStepStart("prove" /* Prove */);
1448
- await sleep(500);
1449
- this.fireStepEnd("prove" /* Prove */);
1469
+ await sleep(proveDelay);
1470
+ this.fireStepEnd("prove" /* Prove */, { isMocks: true, mockSleep: proveDelay });
1450
1471
  this.fireStepStart("verify" /* Verify */);
1451
- await sleep(500);
1472
+ await sleep(verifyDelay);
1452
1473
  const signedResults = await cofheMocksZkVerifySign(
1453
1474
  this.inputItems,
1454
1475
  this.account,
@@ -1463,13 +1484,13 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1463
1484
  utype: this.inputItems[index].utype,
1464
1485
  signature
1465
1486
  }));
1466
- this.fireStepEnd("verify" /* Verify */);
1487
+ this.fireStepEnd("verify" /* Verify */, { isMocks: true, mockSleep: verifyDelay });
1467
1488
  return encryptedInputs;
1468
1489
  }
1469
1490
  /**
1470
1491
  * In the production context, perform a true encryption with the CoFHE coprocessor.
1471
1492
  */
1472
- async productionEncrypt() {
1493
+ async productionExecute() {
1473
1494
  this.assertAccount();
1474
1495
  this.assertChainId();
1475
1496
  this.fireStepStart("initTfhe" /* InitTfhe */);
@@ -1532,15 +1553,15 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1532
1553
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1533
1554
  * .setAccount('0x123...890') // optional
1534
1555
  * .setChainId(11155111) // optional
1535
- * .encrypt(); // execute
1556
+ * .execute(); // execute
1536
1557
  * ```
1537
1558
  *
1538
1559
  * @returns The encrypted inputs.
1539
1560
  */
1540
- async encrypt() {
1561
+ async execute() {
1541
1562
  if (this.chainId === chains.hardhat.id)
1542
- return this.mocksEncrypt();
1543
- return this.productionEncrypt();
1563
+ return this.mocksExecute();
1564
+ return this.productionExecute();
1544
1565
  }
1545
1566
  };
1546
1567
 
@@ -2562,8 +2583,8 @@ var convertViaUtype = (utype, value) => {
2562
2583
  }
2563
2584
  };
2564
2585
 
2565
- // core/decrypt/MockQueryDecrypterAbi.ts
2566
- var MockQueryDecrypterAbi = [
2586
+ // core/decrypt/MockThresholdNetworkAbi.ts
2587
+ var MockThresholdNetworkAbi = [
2567
2588
  {
2568
2589
  type: "function",
2569
2590
  name: "acl",
@@ -2610,11 +2631,7 @@ var MockQueryDecrypterAbi = [
2610
2631
  { name: "expiration", type: "uint64", internalType: "uint64" },
2611
2632
  { name: "recipient", type: "address", internalType: "address" },
2612
2633
  { name: "validatorId", type: "uint256", internalType: "uint256" },
2613
- {
2614
- name: "validatorContract",
2615
- type: "address",
2616
- internalType: "address"
2617
- },
2634
+ { name: "validatorContract", type: "address", internalType: "address" },
2618
2635
  { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2619
2636
  { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2620
2637
  { name: "recipientSignature", type: "bytes", internalType: "bytes" }
@@ -2643,11 +2660,7 @@ var MockQueryDecrypterAbi = [
2643
2660
  { name: "expiration", type: "uint64", internalType: "uint64" },
2644
2661
  { name: "recipient", type: "address", internalType: "address" },
2645
2662
  { name: "validatorId", type: "uint256", internalType: "uint256" },
2646
- {
2647
- name: "validatorContract",
2648
- type: "address",
2649
- internalType: "address"
2650
- },
2663
+ { name: "validatorContract", type: "address", internalType: "address" },
2651
2664
  { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2652
2665
  { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2653
2666
  { name: "recipientSignature", type: "bytes", internalType: "bytes" }
@@ -2671,13 +2684,6 @@ var MockQueryDecrypterAbi = [
2671
2684
  outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
2672
2685
  stateMutability: "pure"
2673
2686
  },
2674
- {
2675
- type: "function",
2676
- name: "taskManager",
2677
- inputs: [],
2678
- outputs: [{ name: "", type: "address", internalType: "contract TaskManager" }],
2679
- stateMutability: "view"
2680
- },
2681
2687
  {
2682
2688
  type: "function",
2683
2689
  name: "unseal",
@@ -2688,15 +2694,80 @@ var MockQueryDecrypterAbi = [
2688
2694
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
2689
2695
  stateMutability: "pure"
2690
2696
  },
2691
- { type: "error", name: "NotAllowed", inputs: [] },
2692
- { type: "error", name: "SealingKeyInvalid", inputs: [] },
2693
- { type: "error", name: "SealingKeyMissing", inputs: [] }
2697
+ {
2698
+ type: "function",
2699
+ name: "mockAcl",
2700
+ inputs: [],
2701
+ outputs: [{ name: "", type: "address", internalType: "contract MockACL" }],
2702
+ stateMutability: "view"
2703
+ },
2704
+ {
2705
+ type: "function",
2706
+ name: "mockTaskManager",
2707
+ inputs: [],
2708
+ outputs: [{ name: "", type: "address", internalType: "contract MockTaskManager" }],
2709
+ stateMutability: "view"
2710
+ },
2711
+ {
2712
+ type: "function",
2713
+ name: "mockQueryDecrypt",
2714
+ inputs: [
2715
+ { name: "ctHash", type: "uint256", internalType: "uint256" },
2716
+ { name: "", type: "uint256", internalType: "uint256" },
2717
+ { name: "issuer", type: "address", internalType: "address" }
2718
+ ],
2719
+ outputs: [
2720
+ { name: "allowed", type: "bool", internalType: "bool" },
2721
+ { name: "error", type: "string", internalType: "string" },
2722
+ { name: "", type: "uint256", internalType: "uint256" }
2723
+ ],
2724
+ stateMutability: "view"
2725
+ },
2726
+ {
2727
+ type: "function",
2728
+ name: "decryptForTxWithPermit",
2729
+ inputs: [
2730
+ { name: "ctHash", type: "uint256", internalType: "uint256" },
2731
+ {
2732
+ name: "permission",
2733
+ type: "tuple",
2734
+ internalType: "struct Permission",
2735
+ components: [
2736
+ { name: "issuer", type: "address", internalType: "address" },
2737
+ { name: "expiration", type: "uint64", internalType: "uint64" },
2738
+ { name: "recipient", type: "address", internalType: "address" },
2739
+ { name: "validatorId", type: "uint256", internalType: "uint256" },
2740
+ { name: "validatorContract", type: "address", internalType: "address" },
2741
+ { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2742
+ { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2743
+ { name: "recipientSignature", type: "bytes", internalType: "bytes" }
2744
+ ]
2745
+ }
2746
+ ],
2747
+ outputs: [
2748
+ { name: "allowed", type: "bool", internalType: "bool" },
2749
+ { name: "error", type: "string", internalType: "string" },
2750
+ { name: "decryptedValue", type: "uint256", internalType: "uint256" }
2751
+ ],
2752
+ stateMutability: "view"
2753
+ },
2754
+ {
2755
+ type: "function",
2756
+ name: "decryptForTxWithoutPermit",
2757
+ inputs: [{ name: "ctHash", type: "uint256", internalType: "uint256" }],
2758
+ outputs: [
2759
+ { name: "allowed", type: "bool", internalType: "bool" },
2760
+ { name: "error", type: "string", internalType: "string" },
2761
+ { name: "decryptedValue", type: "uint256", internalType: "uint256" }
2762
+ ],
2763
+ stateMutability: "view"
2764
+ }
2694
2765
  ];
2695
2766
 
2696
- // core/decrypt/cofheMocksSealOutput.ts
2697
- async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSealOutputDelay) {
2698
- if (mocksSealOutputDelay > 0)
2699
- await sleep(mocksSealOutputDelay);
2767
+ // core/decrypt/cofheMocksDecryptForView.ts
2768
+ async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient, mocksDecryptDelay) {
2769
+ if (mocksDecryptDelay > 0)
2770
+ await sleep(mocksDecryptDelay);
2700
2771
  const permission = PermitUtils.getPermission(permit, true);
2701
2772
  const permissionWithBigInts = {
2702
2773
  ...permission,
@@ -2704,19 +2775,19 @@ async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSe
2704
2775
  validatorId: BigInt(permission.validatorId)
2705
2776
  };
2706
2777
  const [allowed, error, result] = await publicClient.readContract({
2707
- address: MOCKS_QUERY_DECRYPTER_ADDRESS,
2708
- abi: MockQueryDecrypterAbi,
2778
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
2779
+ abi: MockThresholdNetworkAbi,
2709
2780
  functionName: "querySealOutput",
2710
2781
  args: [ctHash, BigInt(utype), permissionWithBigInts]
2711
2782
  });
2712
2783
  if (error != "") {
2713
- throw new CofhesdkError({
2784
+ throw new CofheError({
2714
2785
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2715
2786
  message: `mocks querySealOutput call failed: ${error}`
2716
2787
  });
2717
2788
  }
2718
2789
  if (allowed == false) {
2719
- throw new CofhesdkError({
2790
+ throw new CofheError({
2720
2791
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2721
2792
  message: `mocks querySealOutput call failed: ACL Access Denied (NotAllowed)`
2722
2793
  });
@@ -2735,7 +2806,7 @@ function numberArrayToUint8Array(arr) {
2735
2806
  }
2736
2807
  function convertSealedData(sealed) {
2737
2808
  if (!sealed) {
2738
- throw new CofhesdkError({
2809
+ throw new CofheError({
2739
2810
  code: "SEAL_OUTPUT_RETURNED_NULL" /* SealOutputReturnedNull */,
2740
2811
  message: "Sealed data is missing from completed response"
2741
2812
  });
@@ -2762,7 +2833,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2762
2833
  body: JSON.stringify(body)
2763
2834
  });
2764
2835
  } catch (e) {
2765
- throw new CofhesdkError({
2836
+ throw new CofheError({
2766
2837
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2767
2838
  message: `sealOutput request failed`,
2768
2839
  hint: "Ensure the threshold network URL is valid and reachable.",
@@ -2781,7 +2852,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2781
2852
  } catch {
2782
2853
  errorMessage = response.statusText || errorMessage;
2783
2854
  }
2784
- throw new CofhesdkError({
2855
+ throw new CofheError({
2785
2856
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2786
2857
  message: `sealOutput request failed: ${errorMessage}`,
2787
2858
  hint: "Check the threshold network URL and request parameters.",
@@ -2797,7 +2868,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2797
2868
  try {
2798
2869
  submitResponse = await response.json();
2799
2870
  } catch (e) {
2800
- throw new CofhesdkError({
2871
+ throw new CofheError({
2801
2872
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2802
2873
  message: `Failed to parse sealOutput submit response`,
2803
2874
  cause: e instanceof Error ? e : void 0,
@@ -2808,7 +2879,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2808
2879
  });
2809
2880
  }
2810
2881
  if (!submitResponse.request_id) {
2811
- throw new CofhesdkError({
2882
+ throw new CofheError({
2812
2883
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2813
2884
  message: `sealOutput submit response missing request_id`,
2814
2885
  context: {
@@ -2825,7 +2896,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2825
2896
  let completed = false;
2826
2897
  while (!completed) {
2827
2898
  if (Date.now() - startTime > POLL_TIMEOUT_MS) {
2828
- throw new CofhesdkError({
2899
+ throw new CofheError({
2829
2900
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2830
2901
  message: `sealOutput polling timed out after ${POLL_TIMEOUT_MS}ms`,
2831
2902
  hint: "The request may still be processing. Try again later.",
@@ -2845,7 +2916,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2845
2916
  }
2846
2917
  });
2847
2918
  } catch (e) {
2848
- throw new CofhesdkError({
2919
+ throw new CofheError({
2849
2920
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2850
2921
  message: `sealOutput status poll failed`,
2851
2922
  hint: "Ensure the threshold network URL is valid and reachable.",
@@ -2857,7 +2928,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2857
2928
  });
2858
2929
  }
2859
2930
  if (response.status === 404) {
2860
- throw new CofhesdkError({
2931
+ throw new CofheError({
2861
2932
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2862
2933
  message: `sealOutput request not found: ${requestId}`,
2863
2934
  hint: "The request may have expired or been invalid.",
@@ -2875,7 +2946,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2875
2946
  } catch {
2876
2947
  errorMessage = response.statusText || errorMessage;
2877
2948
  }
2878
- throw new CofhesdkError({
2949
+ throw new CofheError({
2879
2950
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2880
2951
  message: `sealOutput status poll failed: ${errorMessage}`,
2881
2952
  context: {
@@ -2890,7 +2961,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2890
2961
  try {
2891
2962
  statusResponse = await response.json();
2892
2963
  } catch (e) {
2893
- throw new CofhesdkError({
2964
+ throw new CofheError({
2894
2965
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2895
2966
  message: `Failed to parse sealOutput status response`,
2896
2967
  cause: e instanceof Error ? e : void 0,
@@ -2903,7 +2974,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2903
2974
  if (statusResponse.status === "COMPLETED") {
2904
2975
  if (statusResponse.is_succeed === false) {
2905
2976
  const errorMessage = statusResponse.error_message || "Unknown error";
2906
- throw new CofhesdkError({
2977
+ throw new CofheError({
2907
2978
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2908
2979
  message: `sealOutput request failed: ${errorMessage}`,
2909
2980
  context: {
@@ -2914,7 +2985,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2914
2985
  });
2915
2986
  }
2916
2987
  if (!statusResponse.sealed) {
2917
- throw new CofhesdkError({
2988
+ throw new CofheError({
2918
2989
  code: "SEAL_OUTPUT_RETURNED_NULL" /* SealOutputReturnedNull */,
2919
2990
  message: `sealOutput request completed but returned no sealed data`,
2920
2991
  context: {
@@ -2928,7 +2999,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2928
2999
  }
2929
3000
  await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
2930
3001
  }
2931
- throw new CofhesdkError({
3002
+ throw new CofheError({
2932
3003
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2933
3004
  message: "Polling loop exited unexpectedly",
2934
3005
  context: {
@@ -2941,9 +3012,99 @@ async function tnSealOutputV2(ctHash, chainId, permission, thresholdNetworkUrl)
2941
3012
  const requestId = await submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission);
2942
3013
  return await pollSealOutputStatus(thresholdNetworkUrl, requestId);
2943
3014
  }
3015
+ async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient, mocksDecryptForTxDelay) {
3016
+ if (mocksDecryptForTxDelay > 0)
3017
+ await sleep(mocksDecryptForTxDelay);
3018
+ if (permit !== null) {
3019
+ let permission = PermitUtils.getPermission(permit, true);
3020
+ const permissionWithBigInts = {
3021
+ ...permission,
3022
+ expiration: BigInt(permission.expiration),
3023
+ validatorId: BigInt(permission.validatorId)
3024
+ };
3025
+ const [allowed2, error2, result2] = await publicClient.readContract({
3026
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
3027
+ abi: MockThresholdNetworkAbi,
3028
+ functionName: "decryptForTxWithPermit",
3029
+ args: [ctHash, permissionWithBigInts]
3030
+ });
3031
+ if (error2 != "") {
3032
+ throw new CofheError({
3033
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3034
+ message: `mocks decryptForTx call failed: ${error2}`
3035
+ });
3036
+ }
3037
+ if (allowed2 == false) {
3038
+ throw new CofheError({
3039
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3040
+ message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
3041
+ });
3042
+ }
3043
+ const chainId2 = await publicClient.getChainId();
3044
+ const ctHashBigInt2 = BigInt(ctHash);
3045
+ const resultBigInt2 = BigInt(result2);
3046
+ const encryptionType2 = Number((ctHashBigInt2 & 0x7fn << 8n) >> 8n);
3047
+ const ctHashBytes322 = viem.pad(viem.toHex(ctHashBigInt2), { size: 32 });
3048
+ const packed2 = viem.encodePacked(
3049
+ ["uint256", "uint32", "uint64", "bytes32"],
3050
+ [resultBigInt2, encryptionType2, BigInt(chainId2), ctHashBytes322]
3051
+ );
3052
+ const messageHash2 = viem.keccak256(packed2);
3053
+ const signatureHex2 = await accounts.sign({
3054
+ hash: messageHash2,
3055
+ privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
3056
+ to: "hex"
3057
+ });
3058
+ const signature2 = signatureHex2.slice(2);
3059
+ return {
3060
+ ctHash,
3061
+ decryptedValue: BigInt(result2),
3062
+ signature: signature2
3063
+ };
3064
+ }
3065
+ const [allowed, error, result] = await publicClient.readContract({
3066
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
3067
+ abi: MockThresholdNetworkAbi,
3068
+ functionName: "decryptForTxWithoutPermit",
3069
+ args: [ctHash]
3070
+ });
3071
+ if (error != "") {
3072
+ throw new CofheError({
3073
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3074
+ message: `mocks decryptForTx call failed: ${error}`
3075
+ });
3076
+ }
3077
+ if (allowed == false) {
3078
+ throw new CofheError({
3079
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3080
+ message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
3081
+ });
3082
+ }
3083
+ const chainId = await publicClient.getChainId();
3084
+ const ctHashBigInt = BigInt(ctHash);
3085
+ const resultBigInt = BigInt(result);
3086
+ const encryptionType = Number((ctHashBigInt & 0x7fn << 8n) >> 8n);
3087
+ const ctHashBytes32 = viem.pad(viem.toHex(ctHashBigInt), { size: 32 });
3088
+ const packed = viem.encodePacked(
3089
+ ["uint256", "uint32", "uint64", "bytes32"],
3090
+ [resultBigInt, encryptionType, BigInt(chainId), ctHashBytes32]
3091
+ );
3092
+ const messageHash = viem.keccak256(packed);
3093
+ const signatureHex = await accounts.sign({
3094
+ hash: messageHash,
3095
+ privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
3096
+ to: "hex"
3097
+ });
3098
+ const signature = signatureHex.slice(2);
3099
+ return {
3100
+ ctHash,
3101
+ decryptedValue: BigInt(result),
3102
+ signature
3103
+ };
3104
+ }
2944
3105
 
2945
- // core/decrypt/decryptHandleBuilder.ts
2946
- var DecryptHandlesBuilder = class extends BaseBuilder {
3106
+ // core/decrypt/decryptForViewBuilder.ts
3107
+ var DecryptForViewBuilder = class extends BaseBuilder {
2947
3108
  ctHash;
2948
3109
  utype;
2949
3110
  permitHash;
@@ -2969,12 +3130,12 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2969
3130
  *
2970
3131
  * Example:
2971
3132
  * ```typescript
2972
- * const unsealed = await decryptHandle(ctHash, utype)
3133
+ * const unsealed = await client.decryptForView(ctHash, utype)
2973
3134
  * .setChainId(11155111)
2974
- * .decrypt();
3135
+ * .execute();
2975
3136
  * ```
2976
3137
  *
2977
- * @returns The chainable DecryptHandlesBuilder instance.
3138
+ * @returns The chainable DecryptForViewBuilder instance.
2978
3139
  */
2979
3140
  setChainId(chainId) {
2980
3141
  this.chainId = chainId;
@@ -2990,12 +3151,12 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2990
3151
  *
2991
3152
  * Example:
2992
3153
  * ```typescript
2993
- * const unsealed = await decryptHandle(ctHash, utype)
3154
+ * const unsealed = await client.decryptForView(ctHash, utype)
2994
3155
  * .setAccount('0x1234567890123456789012345678901234567890')
2995
- * .decrypt();
3156
+ * .execute();
2996
3157
  * ```
2997
3158
  *
2998
- * @returns The chainable DecryptHandlesBuilder instance.
3159
+ * @returns The chainable DecryptForViewBuilder instance.
2999
3160
  */
3000
3161
  setAccount(account) {
3001
3162
  this.account = account;
@@ -3004,6 +3165,19 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3004
3165
  getAccount() {
3005
3166
  return this.account;
3006
3167
  }
3168
+ withPermit(permitOrPermitHash) {
3169
+ if (typeof permitOrPermitHash === "string") {
3170
+ this.permitHash = permitOrPermitHash;
3171
+ this.permit = void 0;
3172
+ } else if (permitOrPermitHash === void 0) {
3173
+ this.permitHash = void 0;
3174
+ this.permit = void 0;
3175
+ } else {
3176
+ this.permit = permitOrPermitHash;
3177
+ this.permitHash = void 0;
3178
+ }
3179
+ return this;
3180
+ }
3007
3181
  /**
3008
3182
  * @param permitHash - Permit hash to decrypt values from. Used to fetch the correct permit.
3009
3183
  *
@@ -3012,16 +3186,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3012
3186
  *
3013
3187
  * Example:
3014
3188
  * ```typescript
3015
- * const unsealed = await decryptHandle(ctHash, utype)
3189
+ * const unsealed = await client.decryptForView(ctHash, utype)
3016
3190
  * .setPermitHash('0x1234567890123456789012345678901234567890')
3017
- * .decrypt();
3191
+ * .execute();
3018
3192
  * ```
3019
3193
  *
3020
- * @returns The chainable DecryptHandlesBuilder instance.
3194
+ * @returns The chainable DecryptForViewBuilder instance.
3021
3195
  */
3196
+ /** @deprecated Use `withPermit(permitHash)` instead. */
3022
3197
  setPermitHash(permitHash) {
3023
- this.permitHash = permitHash;
3024
- return this;
3198
+ return this.withPermit(permitHash);
3025
3199
  }
3026
3200
  getPermitHash() {
3027
3201
  return this.permitHash;
@@ -3033,16 +3207,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3033
3207
  *
3034
3208
  * Example:
3035
3209
  * ```typescript
3036
- * const unsealed = await decryptHandle(ctHash, utype)
3210
+ * const unsealed = await client.decryptForView(ctHash, utype)
3037
3211
  * .setPermit(permit)
3038
- * .decrypt();
3212
+ * .execute();
3039
3213
  * ```
3040
3214
  *
3041
- * @returns The chainable DecryptHandlesBuilder instance.
3215
+ * @returns The chainable DecryptForViewBuilder instance.
3042
3216
  */
3217
+ /** @deprecated Use `withPermit(permit)` instead. */
3043
3218
  setPermit(permit) {
3044
- this.permit = permit;
3045
- return this;
3219
+ return this.withPermit(permit);
3046
3220
  }
3047
3221
  getPermit() {
3048
3222
  return this.permit;
@@ -3053,7 +3227,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3053
3227
  }
3054
3228
  validateUtypeOrThrow() {
3055
3229
  if (!isValidUtype(this.utype))
3056
- throw new CofhesdkError({
3230
+ throw new CofheError({
3057
3231
  code: "INVALID_UTYPE" /* InvalidUtype */,
3058
3232
  message: `Invalid utype to decrypt to`,
3059
3233
  context: {
@@ -3069,7 +3243,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3069
3243
  if (this.permitHash) {
3070
3244
  const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
3071
3245
  if (!permit2) {
3072
- throw new CofhesdkError({
3246
+ throw new CofheError({
3073
3247
  code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
3074
3248
  message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
3075
3249
  hint: "Ensure the permit exists and is valid.",
@@ -3084,7 +3258,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3084
3258
  }
3085
3259
  const permit = await permits.getActivePermit(this.chainId, this.account);
3086
3260
  if (!permit) {
3087
- throw new CofhesdkError({
3261
+ throw new CofheError({
3088
3262
  code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
3089
3263
  message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
3090
3264
  hint: "Ensure a permit exists for this account on this chain.",
@@ -3101,8 +3275,8 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3101
3275
  */
3102
3276
  async mocksSealOutput(permit) {
3103
3277
  this.assertPublicClient();
3104
- const mocksSealOutputDelay = this.config.mocks.sealOutputDelay;
3105
- return cofheMocksSealOutput(this.ctHash, this.utype, permit, this.publicClient, mocksSealOutputDelay);
3278
+ const mocksDecryptDelay = this.config.mocks.decryptDelay;
3279
+ return cofheMocksDecryptForView(this.ctHash, this.utype, permit, this.publicClient, mocksDecryptDelay);
3106
3280
  }
3107
3281
  /**
3108
3282
  * In the production context, perform a true decryption with the CoFHE coprocessor.
@@ -3127,15 +3301,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3127
3301
  *
3128
3302
  * Example:
3129
3303
  * ```typescript
3130
- * const unsealed = await decryptHandle(ctHash, utype)
3304
+ * const unsealed = await client.decryptForView(ctHash, utype)
3131
3305
  * .setChainId(11155111) // optional
3132
3306
  * .setAccount('0x123...890') // optional
3133
- * .decrypt(); // execute
3307
+ * .withPermit() // optional
3308
+ * .execute(); // execute
3134
3309
  * ```
3135
3310
  *
3136
3311
  * @returns The unsealed item.
3137
3312
  */
3138
- async decrypt() {
3313
+ async execute() {
3139
3314
  this.validateUtypeOrThrow();
3140
3315
  const permit = await this.getResolvedPermit();
3141
3316
  PermitUtils.validate(permit);
@@ -3151,6 +3326,394 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3151
3326
  }
3152
3327
  };
3153
3328
 
3329
+ // core/decrypt/tnDecrypt.ts
3330
+ function normalizeSignature(signature) {
3331
+ if (typeof signature !== "string") {
3332
+ throw new CofheError({
3333
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3334
+ message: "decrypt response missing signature",
3335
+ context: {
3336
+ signature
3337
+ }
3338
+ });
3339
+ }
3340
+ const trimmed = signature.trim();
3341
+ if (trimmed.length === 0) {
3342
+ throw new CofheError({
3343
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3344
+ message: "decrypt response returned empty signature"
3345
+ });
3346
+ }
3347
+ return trimmed.startsWith("0x") ? trimmed.slice(2) : trimmed;
3348
+ }
3349
+ function parseDecryptedBytesToBigInt(decrypted) {
3350
+ if (!Array.isArray(decrypted)) {
3351
+ throw new CofheError({
3352
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3353
+ message: "decrypt response field <decrypted> must be a byte array",
3354
+ context: {
3355
+ decrypted
3356
+ }
3357
+ });
3358
+ }
3359
+ if (decrypted.length === 0) {
3360
+ throw new CofheError({
3361
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3362
+ message: "decrypt response field <decrypted> was an empty byte array",
3363
+ context: {
3364
+ decrypted
3365
+ }
3366
+ });
3367
+ }
3368
+ let hex = "";
3369
+ for (const b of decrypted) {
3370
+ if (typeof b !== "number" || !Number.isInteger(b) || b < 0 || b > 255) {
3371
+ throw new CofheError({
3372
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3373
+ message: "decrypt response field <decrypted> contained a non-byte value",
3374
+ context: {
3375
+ badElement: b,
3376
+ decrypted
3377
+ }
3378
+ });
3379
+ }
3380
+ hex += b.toString(16).padStart(2, "0");
3381
+ }
3382
+ return BigInt(`0x${hex}`);
3383
+ }
3384
+ function assertTnDecryptResponse(value) {
3385
+ if (value == null || typeof value !== "object") {
3386
+ throw new CofheError({
3387
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3388
+ message: "decrypt response must be a JSON object",
3389
+ context: {
3390
+ value
3391
+ }
3392
+ });
3393
+ }
3394
+ const v = value;
3395
+ const decrypted = v.decrypted;
3396
+ const signature = v.signature;
3397
+ const encryptionType = v.encryption_type;
3398
+ const errorMessage = v.error_message;
3399
+ if (!Array.isArray(decrypted)) {
3400
+ throw new CofheError({
3401
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3402
+ message: "decrypt response missing <decrypted> byte array",
3403
+ context: { decryptResponse: value }
3404
+ });
3405
+ }
3406
+ if (typeof signature !== "string") {
3407
+ throw new CofheError({
3408
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3409
+ message: "decrypt response missing <signature> string",
3410
+ context: { decryptResponse: value }
3411
+ });
3412
+ }
3413
+ if (typeof encryptionType !== "number") {
3414
+ throw new CofheError({
3415
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3416
+ message: "decrypt response missing <encryption_type> number",
3417
+ context: { decryptResponse: value }
3418
+ });
3419
+ }
3420
+ if (!(typeof errorMessage === "string" || errorMessage === null)) {
3421
+ throw new CofheError({
3422
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3423
+ message: "decrypt response field <error_message> must be string or null",
3424
+ context: { decryptResponse: value }
3425
+ });
3426
+ }
3427
+ return {
3428
+ decrypted,
3429
+ signature,
3430
+ encryption_type: encryptionType,
3431
+ error_message: errorMessage
3432
+ };
3433
+ }
3434
+ async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
3435
+ const body = {
3436
+ ct_tempkey: ctHash.toString(16).padStart(64, "0"),
3437
+ host_chain_id: chainId
3438
+ };
3439
+ if (permission) {
3440
+ body.permit = permission;
3441
+ }
3442
+ let response;
3443
+ try {
3444
+ response = await fetch(`${thresholdNetworkUrl}/decrypt`, {
3445
+ method: "POST",
3446
+ headers: {
3447
+ "Content-Type": "application/json"
3448
+ },
3449
+ body: JSON.stringify(body)
3450
+ });
3451
+ } catch (e) {
3452
+ throw new CofheError({
3453
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3454
+ message: `decrypt request failed`,
3455
+ hint: "Ensure the threshold network URL is valid and reachable.",
3456
+ cause: e instanceof Error ? e : void 0,
3457
+ context: {
3458
+ thresholdNetworkUrl,
3459
+ body
3460
+ }
3461
+ });
3462
+ }
3463
+ const responseText = await response.text();
3464
+ if (!response.ok) {
3465
+ let errorMessage = response.statusText || `HTTP ${response.status}`;
3466
+ try {
3467
+ const errorBody = JSON.parse(responseText);
3468
+ const maybeMessage = errorBody.error_message || errorBody.message;
3469
+ if (typeof maybeMessage === "string" && maybeMessage.length > 0)
3470
+ errorMessage = maybeMessage;
3471
+ } catch {
3472
+ const trimmed = responseText.trim();
3473
+ if (trimmed.length > 0)
3474
+ errorMessage = trimmed;
3475
+ }
3476
+ throw new CofheError({
3477
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3478
+ message: `decrypt request failed: ${errorMessage}`,
3479
+ hint: "Check the threshold network URL and request parameters.",
3480
+ context: {
3481
+ thresholdNetworkUrl,
3482
+ status: response.status,
3483
+ statusText: response.statusText,
3484
+ body,
3485
+ responseText
3486
+ }
3487
+ });
3488
+ }
3489
+ let rawJson;
3490
+ try {
3491
+ rawJson = JSON.parse(responseText);
3492
+ } catch (e) {
3493
+ throw new CofheError({
3494
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3495
+ message: `Failed to parse decrypt response`,
3496
+ cause: e instanceof Error ? e : void 0,
3497
+ context: {
3498
+ thresholdNetworkUrl,
3499
+ body,
3500
+ responseText
3501
+ }
3502
+ });
3503
+ }
3504
+ const decryptResponse = assertTnDecryptResponse(rawJson);
3505
+ if (decryptResponse.error_message) {
3506
+ throw new CofheError({
3507
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3508
+ message: `decrypt request failed: ${decryptResponse.error_message}`,
3509
+ context: {
3510
+ thresholdNetworkUrl,
3511
+ body,
3512
+ decryptResponse
3513
+ }
3514
+ });
3515
+ }
3516
+ const decryptedValue = parseDecryptedBytesToBigInt(decryptResponse.decrypted);
3517
+ const signature = normalizeSignature(decryptResponse.signature);
3518
+ return { decryptedValue, signature };
3519
+ }
3520
+
3521
+ // core/decrypt/decryptForTxBuilder.ts
3522
+ var DecryptForTxBuilder = class extends BaseBuilder {
3523
+ ctHash;
3524
+ permitHash;
3525
+ permit;
3526
+ permitSelection = "unset";
3527
+ constructor(params) {
3528
+ super({
3529
+ config: params.config,
3530
+ publicClient: params.publicClient,
3531
+ walletClient: params.walletClient,
3532
+ chainId: params.chainId,
3533
+ account: params.account,
3534
+ requireConnected: params.requireConnected
3535
+ });
3536
+ this.ctHash = params.ctHash;
3537
+ }
3538
+ setChainId(chainId) {
3539
+ this.chainId = chainId;
3540
+ return this;
3541
+ }
3542
+ getChainId() {
3543
+ return this.chainId;
3544
+ }
3545
+ setAccount(account) {
3546
+ this.account = account;
3547
+ return this;
3548
+ }
3549
+ getAccount() {
3550
+ return this.account;
3551
+ }
3552
+ withPermit(permitOrPermitHash) {
3553
+ if (this.permitSelection === "with-permit") {
3554
+ throw new CofheError({
3555
+ code: "INTERNAL_ERROR" /* InternalError */,
3556
+ message: "decryptForTx: withPermit() can only be selected once.",
3557
+ hint: "Choose the permit mode once. If you need a different permit, start a new decryptForTx() builder chain."
3558
+ });
3559
+ }
3560
+ if (this.permitSelection === "without-permit") {
3561
+ throw new CofheError({
3562
+ code: "INTERNAL_ERROR" /* InternalError */,
3563
+ message: "decryptForTx: cannot call withPermit() after withoutPermit() has been selected.",
3564
+ hint: "Choose exactly one permit mode: either call .withPermit(...) or .withoutPermit(), but not both."
3565
+ });
3566
+ }
3567
+ this.permitSelection = "with-permit";
3568
+ if (typeof permitOrPermitHash === "string") {
3569
+ this.permitHash = permitOrPermitHash;
3570
+ this.permit = void 0;
3571
+ } else if (permitOrPermitHash === void 0) {
3572
+ this.permitHash = void 0;
3573
+ this.permit = void 0;
3574
+ } else {
3575
+ this.permit = permitOrPermitHash;
3576
+ this.permitHash = void 0;
3577
+ }
3578
+ return this;
3579
+ }
3580
+ /**
3581
+ * Select "no permit" mode.
3582
+ *
3583
+ * This uses global allowance (no permit required) and sends an empty permission payload to `/decrypt`.
3584
+ */
3585
+ withoutPermit() {
3586
+ if (this.permitSelection === "without-permit") {
3587
+ throw new CofheError({
3588
+ code: "INTERNAL_ERROR" /* InternalError */,
3589
+ message: "decryptForTx: withoutPermit() can only be selected once.",
3590
+ hint: "Choose the permit mode once. If you need a different mode, start a new decryptForTx() builder chain."
3591
+ });
3592
+ }
3593
+ if (this.permitSelection === "with-permit") {
3594
+ throw new CofheError({
3595
+ code: "INTERNAL_ERROR" /* InternalError */,
3596
+ message: "decryptForTx: cannot call withoutPermit() after withPermit() has been selected.",
3597
+ hint: "Choose exactly one permit mode: either call .withPermit(...) or .withoutPermit(), but not both."
3598
+ });
3599
+ }
3600
+ this.permitSelection = "without-permit";
3601
+ this.permitHash = void 0;
3602
+ this.permit = void 0;
3603
+ return this;
3604
+ }
3605
+ getPermit() {
3606
+ return this.permit;
3607
+ }
3608
+ getPermitHash() {
3609
+ return this.permitHash;
3610
+ }
3611
+ async getThresholdNetworkUrl() {
3612
+ this.assertChainId();
3613
+ return getThresholdNetworkUrlOrThrow(this.config, this.chainId);
3614
+ }
3615
+ async getResolvedPermit() {
3616
+ if (this.permitSelection === "unset") {
3617
+ throw new CofheError({
3618
+ code: "INTERNAL_ERROR" /* InternalError */,
3619
+ message: "decryptForTx: missing permit selection; call withPermit(...) or withoutPermit() before execute().",
3620
+ hint: "Call .withPermit() to use the active permit, or .withoutPermit() for global allowance."
3621
+ });
3622
+ }
3623
+ if (this.permitSelection === "without-permit") {
3624
+ return null;
3625
+ }
3626
+ if (this.permit)
3627
+ return this.permit;
3628
+ this.assertChainId();
3629
+ this.assertAccount();
3630
+ if (this.permitHash) {
3631
+ const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
3632
+ if (!permit2) {
3633
+ throw new CofheError({
3634
+ code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
3635
+ message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
3636
+ hint: "Ensure the permit exists and is valid.",
3637
+ context: {
3638
+ chainId: this.chainId,
3639
+ account: this.account,
3640
+ permitHash: this.permitHash
3641
+ }
3642
+ });
3643
+ }
3644
+ return permit2;
3645
+ }
3646
+ const permit = await permits.getActivePermit(this.chainId, this.account);
3647
+ if (!permit) {
3648
+ throw new CofheError({
3649
+ code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
3650
+ message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
3651
+ hint: "Create a permit (e.g. client.permits.createSelf(...)) and/or set it active (client.permits.selectActivePermit(hash)).",
3652
+ context: {
3653
+ chainId: this.chainId,
3654
+ account: this.account
3655
+ }
3656
+ });
3657
+ }
3658
+ return permit;
3659
+ }
3660
+ /**
3661
+ * On hardhat, interact with MockThresholdNetwork contract
3662
+ */
3663
+ async mocksDecryptForTx(permit) {
3664
+ this.assertPublicClient();
3665
+ const delay = this.config.mocks.decryptDelay;
3666
+ const result = await cofheMocksDecryptForTx(this.ctHash, 0, permit, this.publicClient, delay);
3667
+ return result;
3668
+ }
3669
+ /**
3670
+ * In the production context, perform a true decryption with the CoFHE coprocessor.
3671
+ */
3672
+ async productionDecryptForTx(permit) {
3673
+ this.assertChainId();
3674
+ this.assertPublicClient();
3675
+ const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
3676
+ const permission = permit ? PermitUtils.getPermission(permit, true) : null;
3677
+ const { decryptedValue, signature } = await tnDecrypt(this.ctHash, this.chainId, permission, thresholdNetworkUrl);
3678
+ return {
3679
+ ctHash: this.ctHash,
3680
+ decryptedValue,
3681
+ signature
3682
+ };
3683
+ }
3684
+ /**
3685
+ * Final step of the decryptForTx process. MUST BE CALLED LAST IN THE CHAIN.
3686
+ *
3687
+ * You must explicitly choose one permit mode before calling `execute()`:
3688
+ * - `withPermit(permit)` / `withPermit(permitHash)` / `withPermit()` (active permit)
3689
+ * - `withoutPermit()` (global allowance)
3690
+ */
3691
+ async execute() {
3692
+ const permit = await this.getResolvedPermit();
3693
+ if (permit !== null) {
3694
+ PermitUtils.validate(permit);
3695
+ PermitUtils.isValid(permit);
3696
+ const chainId = permit._signedDomain.chainId;
3697
+ if (chainId === hardhat2.id) {
3698
+ return await this.mocksDecryptForTx(permit);
3699
+ } else {
3700
+ return await this.productionDecryptForTx(permit);
3701
+ }
3702
+ } else {
3703
+ if (!this.chainId) {
3704
+ this.assertPublicClient();
3705
+ this.chainId = await getPublicClientChainID(this.publicClient);
3706
+ }
3707
+ this.assertChainId();
3708
+ if (this.chainId === hardhat2.id) {
3709
+ return await this.mocksDecryptForTx(null);
3710
+ } else {
3711
+ return await this.productionDecryptForTx(null);
3712
+ }
3713
+ }
3714
+ }
3715
+ };
3716
+
3154
3717
  // core/client.ts
3155
3718
  var InitialConnectStore = {
3156
3719
  connected: false,
@@ -3161,7 +3724,7 @@ var InitialConnectStore = {
3161
3724
  publicClient: void 0,
3162
3725
  walletClient: void 0
3163
3726
  };
3164
- function createCofhesdkClientBase(opts) {
3727
+ function createCofheClientBase(opts) {
3165
3728
  const keysStorage = createKeysStore(opts.config.fheKeyStorage);
3166
3729
  const connectStore = vanilla.createStore(() => InitialConnectStore);
3167
3730
  let connectAttemptId = 0;
@@ -3172,7 +3735,7 @@ function createCofhesdkClientBase(opts) {
3172
3735
  const state = connectStore.getState();
3173
3736
  const notConnected = !state.connected || !state.account || !state.chainId || !state.publicClient || !state.walletClient;
3174
3737
  if (notConnected) {
3175
- throw new CofhesdkError({
3738
+ throw new CofheError({
3176
3739
  code: "NOT_CONNECTED" /* NotConnected */,
3177
3740
  message: "Client must be connected, account and chainId must be initialized",
3178
3741
  hint: "Ensure client.connect() has been called and awaited.",
@@ -3243,16 +3806,28 @@ function createCofhesdkClientBase(opts) {
3243
3806
  requireConnected: _requireConnected
3244
3807
  });
3245
3808
  }
3246
- function decryptHandle(ctHash, utype) {
3809
+ function decryptForView(ctHash, utype) {
3247
3810
  const state = connectStore.getState();
3248
- return new DecryptHandlesBuilder({
3811
+ return new DecryptForViewBuilder({
3249
3812
  ctHash,
3250
3813
  utype,
3251
- chainId: state.chainId ?? void 0,
3252
- account: state.account ?? void 0,
3814
+ chainId: state.chainId,
3815
+ account: state.account,
3253
3816
  config: opts.config,
3254
- publicClient: state.publicClient ?? void 0,
3255
- walletClient: state.walletClient ?? void 0,
3817
+ publicClient: state.publicClient,
3818
+ walletClient: state.walletClient,
3819
+ requireConnected: _requireConnected
3820
+ });
3821
+ }
3822
+ function decryptForTx(ctHash) {
3823
+ const state = connectStore.getState();
3824
+ return new DecryptForTxBuilder({
3825
+ ctHash,
3826
+ chainId: state.chainId,
3827
+ account: state.account,
3828
+ config: opts.config,
3829
+ publicClient: state.publicClient,
3830
+ walletClient: state.walletClient,
3256
3831
  requireConnected: _requireConnected
3257
3832
  });
3258
3833
  }
@@ -3261,7 +3836,7 @@ function createCofhesdkClientBase(opts) {
3261
3836
  const _chainId = chainId ?? state.chainId;
3262
3837
  const _account = account ?? state.account;
3263
3838
  if (_chainId == null || _account == null) {
3264
- throw new CofhesdkError({
3839
+ throw new CofheError({
3265
3840
  code: "NOT_CONNECTED" /* NotConnected */,
3266
3841
  message: "ChainId or account not available.",
3267
3842
  hint: "Ensure client.connect() has been called, or provide chainId and account explicitly.",
@@ -3346,6 +3921,9 @@ function createCofhesdkClientBase(opts) {
3346
3921
  getSnapshot: connectStore.getState,
3347
3922
  subscribe: connectStore.subscribe,
3348
3923
  // flags (read-only: reflect snapshot)
3924
+ get connection() {
3925
+ return connectStore.getState();
3926
+ },
3349
3927
  get connected() {
3350
3928
  return connectStore.getState().connected;
3351
3929
  },
@@ -3357,7 +3935,12 @@ function createCofhesdkClientBase(opts) {
3357
3935
  connect,
3358
3936
  disconnect,
3359
3937
  encryptInputs,
3360
- decryptHandle,
3938
+ decryptForView,
3939
+ /**
3940
+ * @deprecated Use `decryptForView` instead. Kept for backward compatibility.
3941
+ */
3942
+ decryptHandle: decryptForView,
3943
+ decryptForTx,
3361
3944
  permits: clientPermits
3362
3945
  // Add SDK-specific methods below that require connection
3363
3946
  // Example:
@@ -3570,15 +4153,15 @@ async function zkProveWithWorker2(fheKeyHex, crsHex, items, metadata) {
3570
4153
  const workerManager2 = getWorkerManager();
3571
4154
  return await workerManager2.submitProof(fheKeyHex, crsHex, serializedItems, metadata);
3572
4155
  }
3573
- function createCofhesdkConfig(config) {
3574
- return createCofhesdkConfigBase({
4156
+ function createCofheConfig(config) {
4157
+ return createCofheConfigBase({
3575
4158
  environment: "web",
3576
4159
  ...config,
3577
4160
  fheKeyStorage: config.fheKeyStorage === null ? null : config.fheKeyStorage ?? createWebStorage()
3578
4161
  });
3579
4162
  }
3580
- function createCofhesdkClient(config) {
3581
- return createCofhesdkClientBase({
4163
+ function createCofheClient(config) {
4164
+ return createCofheClientBase({
3582
4165
  config,
3583
4166
  zkBuilderAndCrsGenerator,
3584
4167
  tfhePublicKeyDeserializer,
@@ -3589,8 +4172,8 @@ function createCofhesdkClient(config) {
3589
4172
  zkProveWorkerFn: areWorkersAvailable() ? zkProveWithWorker2 : void 0
3590
4173
  });
3591
4174
  }
3592
- function createCofhesdkClientWithCustomWorker(config, customZkProveWorkerFn) {
3593
- return createCofhesdkClientBase({
4175
+ function createCofheClientWithCustomWorker(config, customZkProveWorkerFn) {
4176
+ return createCofheClientBase({
3594
4177
  config,
3595
4178
  zkBuilderAndCrsGenerator,
3596
4179
  tfhePublicKeyDeserializer,
@@ -3601,7 +4184,7 @@ function createCofhesdkClientWithCustomWorker(config, customZkProveWorkerFn) {
3601
4184
  }
3602
4185
 
3603
4186
  exports.areWorkersAvailable = areWorkersAvailable;
3604
- exports.createCofhesdkClient = createCofhesdkClient;
3605
- exports.createCofhesdkClientWithCustomWorker = createCofhesdkClientWithCustomWorker;
3606
- exports.createCofhesdkConfig = createCofhesdkConfig;
4187
+ exports.createCofheClient = createCofheClient;
4188
+ exports.createCofheClientWithCustomWorker = createCofheClientWithCustomWorker;
4189
+ exports.createCofheConfig = createCofheConfig;
3607
4190
  exports.terminateWorker = terminateWorker;