@cofhe/sdk 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/chains/defineChain.ts +2 -2
  3. package/chains/types.ts +3 -3
  4. package/core/baseBuilder.ts +18 -18
  5. package/core/client.test.ts +155 -41
  6. package/core/client.ts +72 -32
  7. package/core/clientTypes.ts +28 -18
  8. package/core/config.test.ts +40 -33
  9. package/core/config.ts +56 -51
  10. package/core/consts.ts +22 -0
  11. package/core/decrypt/{MockQueryDecrypterAbi.ts → MockThresholdNetworkAbi.ts} +71 -21
  12. package/core/decrypt/cofheMocksDecryptForTx.ts +142 -0
  13. package/core/decrypt/{cofheMocksSealOutput.ts → cofheMocksDecryptForView.ts} +12 -14
  14. package/core/decrypt/decryptForTxBuilder.ts +340 -0
  15. package/core/decrypt/{decryptHandleBuilder.ts → decryptForViewBuilder.ts} +75 -42
  16. package/core/decrypt/tnDecrypt.ts +232 -0
  17. package/core/decrypt/tnSealOutputV1.ts +5 -5
  18. package/core/decrypt/tnSealOutputV2.ts +27 -27
  19. package/core/encrypt/cofheMocksZkVerifySign.ts +19 -26
  20. package/core/encrypt/encryptInputsBuilder.test.ts +57 -61
  21. package/core/encrypt/encryptInputsBuilder.ts +65 -42
  22. package/core/encrypt/zkPackProveVerify.ts +11 -11
  23. package/core/error.ts +18 -18
  24. package/core/fetchKeys.test.ts +3 -3
  25. package/core/fetchKeys.ts +3 -3
  26. package/core/index.ts +22 -11
  27. package/core/permits.test.ts +5 -6
  28. package/core/permits.ts +5 -4
  29. package/core/utils.ts +10 -10
  30. package/dist/chains.cjs +4 -7
  31. package/dist/chains.d.cts +12 -12
  32. package/dist/chains.d.ts +12 -12
  33. package/dist/chains.js +1 -1
  34. package/dist/{chunk-WGCRJCBR.js → chunk-2TPSCOW3.js} +820 -224
  35. package/dist/{chunk-UGBVZNRT.js → chunk-NWDKXBIP.js} +309 -189
  36. package/dist/{chunk-WEAZ25JO.js → chunk-TBLR7NNE.js} +4 -7
  37. package/dist/{clientTypes-5_1nwtUe.d.cts → clientTypes-6aTZPQ_4.d.ts} +233 -173
  38. package/dist/{clientTypes-Es7fyi65.d.ts → clientTypes-Bhq7pCSA.d.cts} +233 -173
  39. package/dist/core.cjs +1138 -418
  40. package/dist/core.d.cts +37 -24
  41. package/dist/core.d.ts +37 -24
  42. package/dist/core.js +3 -3
  43. package/dist/node.cjs +1082 -370
  44. package/dist/node.d.cts +12 -12
  45. package/dist/node.d.ts +12 -12
  46. package/dist/node.js +8 -8
  47. package/dist/{permit-fUSe6KKq.d.cts → permit-MZ502UBl.d.cts} +30 -33
  48. package/dist/{permit-fUSe6KKq.d.ts → permit-MZ502UBl.d.ts} +30 -33
  49. package/dist/permits.cjs +305 -187
  50. package/dist/permits.d.cts +111 -812
  51. package/dist/permits.d.ts +111 -812
  52. package/dist/permits.js +1 -1
  53. package/dist/types-YiAC4gig.d.cts +33 -0
  54. package/dist/types-YiAC4gig.d.ts +33 -0
  55. package/dist/web.cjs +1085 -373
  56. package/dist/web.d.cts +13 -13
  57. package/dist/web.d.ts +13 -13
  58. package/dist/web.js +10 -10
  59. package/node/client.test.ts +34 -34
  60. package/node/config.test.ts +11 -11
  61. package/node/encryptInputs.test.ts +29 -29
  62. package/node/index.ts +15 -15
  63. package/package.json +3 -3
  64. package/permits/localstorage.test.ts +9 -13
  65. package/permits/onchain-utils.ts +221 -0
  66. package/permits/permit.test.ts +51 -5
  67. package/permits/permit.ts +28 -74
  68. package/permits/store.test.ts +10 -50
  69. package/permits/store.ts +4 -14
  70. package/permits/test-utils.ts +10 -2
  71. package/permits/types.ts +22 -9
  72. package/permits/utils.ts +0 -4
  73. package/permits/validation.test.ts +29 -32
  74. package/permits/validation.ts +112 -194
  75. package/web/client.web.test.ts +34 -34
  76. package/web/config.web.test.ts +11 -11
  77. package/web/encryptInputs.web.test.ts +29 -29
  78. package/web/index.ts +19 -19
  79. package/web/worker.builder.web.test.ts +28 -28
  80. package/web/worker.config.web.test.ts +47 -47
  81. package/web/worker.output.web.test.ts +10 -10
  82. package/dist/types-KImPrEIe.d.cts +0 -48
  83. package/dist/types-KImPrEIe.d.ts +0 -48
package/dist/node.cjs CHANGED
@@ -35,7 +35,7 @@ var nacl__namespace = /*#__PURE__*/_interopNamespace(nacl);
35
35
  // core/client.ts
36
36
 
37
37
  // core/error.ts
38
- var CofhesdkError = class _CofhesdkError extends Error {
38
+ var CofheError = class _CofheError extends Error {
39
39
  code;
40
40
  cause;
41
41
  hint;
@@ -43,25 +43,25 @@ var CofhesdkError = class _CofhesdkError extends Error {
43
43
  constructor({ code, message, cause, hint, context }) {
44
44
  const fullMessage = cause ? `${message} | Caused by: ${cause.message}` : message;
45
45
  super(fullMessage);
46
- this.name = "CofhesdkError";
46
+ this.name = "CofheError";
47
47
  this.code = code;
48
48
  this.cause = cause;
49
49
  this.hint = hint;
50
50
  this.context = context;
51
51
  if (Error.captureStackTrace) {
52
- Error.captureStackTrace(this, _CofhesdkError);
52
+ Error.captureStackTrace(this, _CofheError);
53
53
  }
54
54
  }
55
55
  /**
56
- * Creates a CofhesdkError from an unknown error
57
- * If the error is a CofhesdkError, it is returned unchanged, else a new CofhesdkError is created
58
- * If a wrapperError is provided, it is used to create the new CofhesdkError, else a default is used
56
+ * Creates a CofheError from an unknown error
57
+ * If the error is a CofheError, it is returned unchanged, else a new CofheError is created
58
+ * If a wrapperError is provided, it is used to create the new CofheError, else a default is used
59
59
  */
60
60
  static fromError(error, wrapperError) {
61
- if (isCofhesdkError(error))
61
+ if (isCofheError(error))
62
62
  return error;
63
63
  const cause = error instanceof Error ? error : new Error(`${error}`);
64
- return new _CofhesdkError({
64
+ return new _CofheError({
65
65
  code: wrapperError?.code ?? "INTERNAL_ERROR" /* InternalError */,
66
66
  message: wrapperError?.message ?? "An internal error occurred",
67
67
  hint: wrapperError?.hint,
@@ -121,7 +121,7 @@ var bigintSafeJsonStringify = (value) => {
121
121
  return value2;
122
122
  });
123
123
  };
124
- var isCofhesdkError = (error) => error instanceof CofhesdkError;
124
+ var isCofheError = (error) => error instanceof CofheError;
125
125
 
126
126
  // core/types.ts
127
127
  var FheUintUTypes = [
@@ -165,14 +165,14 @@ async function getPublicClientChainID(publicClient) {
165
165
  try {
166
166
  chainId = publicClient.chain?.id ?? await publicClient.getChainId();
167
167
  } catch (e) {
168
- throw new CofhesdkError({
168
+ throw new CofheError({
169
169
  code: "PUBLIC_WALLET_GET_CHAIN_ID_FAILED" /* PublicWalletGetChainIdFailed */,
170
170
  message: "getting chain ID from public client failed",
171
171
  cause: e instanceof Error ? e : void 0
172
172
  });
173
173
  }
174
174
  if (chainId === null) {
175
- throw new CofhesdkError({
175
+ throw new CofheError({
176
176
  code: "PUBLIC_WALLET_GET_CHAIN_ID_FAILED" /* PublicWalletGetChainIdFailed */,
177
177
  message: "chain ID from public client is null"
178
178
  });
@@ -187,14 +187,14 @@ async function getWalletClientAccount(walletClient) {
187
187
  address = (await walletClient.getAddresses())?.[0];
188
188
  }
189
189
  } catch (e) {
190
- throw new CofhesdkError({
190
+ throw new CofheError({
191
191
  code: "PUBLIC_WALLET_GET_ADDRESSES_FAILED" /* PublicWalletGetAddressesFailed */,
192
192
  message: "getting address from wallet client failed",
193
193
  cause: e instanceof Error ? e : void 0
194
194
  });
195
195
  }
196
196
  if (!address) {
197
- throw new CofhesdkError({
197
+ throw new CofheError({
198
198
  code: "PUBLIC_WALLET_GET_ADDRESSES_FAILED" /* PublicWalletGetAddressesFailed */,
199
199
  message: "address from wallet client is null"
200
200
  });
@@ -262,7 +262,7 @@ var zkPack = (items, builder) => {
262
262
  break;
263
263
  }
264
264
  default: {
265
- throw new CofhesdkError({
265
+ throw new CofheError({
266
266
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
267
267
  message: `Invalid utype: ${item.utype}`,
268
268
  hint: `Ensure that the utype is valid, using the Encryptable type, for example: Encryptable.uint128(100n)`,
@@ -274,7 +274,7 @@ var zkPack = (items, builder) => {
274
274
  }
275
275
  }
276
276
  if (totalBits > MAX_ENCRYPTABLE_BITS) {
277
- throw new CofhesdkError({
277
+ throw new CofheError({
278
278
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
279
279
  message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
280
280
  hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
@@ -338,14 +338,14 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
338
338
  });
339
339
  if (!response.ok) {
340
340
  const errorBody = await response.text();
341
- throw new CofhesdkError({
341
+ throw new CofheError({
342
342
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
343
343
  message: `HTTP error! ZK proof verification failed - ${errorBody}`
344
344
  });
345
345
  }
346
346
  const json = await response.json();
347
347
  if (json.status !== "success") {
348
- throw new CofhesdkError({
348
+ throw new CofheError({
349
349
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
350
350
  message: `ZK proof verification response malformed - ${json.error}`
351
351
  });
@@ -357,7 +357,7 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
357
357
  };
358
358
  });
359
359
  } catch (e) {
360
- throw new CofhesdkError({
360
+ throw new CofheError({
361
361
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
362
362
  message: `ZK proof verification failed`,
363
363
  cause: e instanceof Error ? e : void 0
@@ -475,8 +475,15 @@ var MockZkVerifierAbi = [
475
475
  },
476
476
  { type: "error", name: "InvalidInputs", inputs: [] }
477
477
  ];
478
- var MocksZkVerifierAddress = "0x0000000000000000000000000000000000000100";
478
+
479
+ // core/consts.ts
480
+ var TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
481
+ var MOCKS_ZK_VERIFIER_ADDRESS = "0x0000000000000000000000000000000000005001";
482
+ var MOCKS_THRESHOLD_NETWORK_ADDRESS = "0x0000000000000000000000000000000000005002";
479
483
  var MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = "0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512";
484
+ var MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d";
485
+
486
+ // core/encrypt/cofheMocksZkVerifySign.ts
480
487
  function createMockZkVerifierSigner() {
481
488
  return viem.createWalletClient({
482
489
  chain: chains.hardhat,
@@ -519,7 +526,7 @@ async function cofheMocksCheckEncryptableBits(items) {
519
526
  }
520
527
  }
521
528
  if (totalBits > MAX_ENCRYPTABLE_BITS) {
522
- throw new CofhesdkError({
529
+ throw new CofheError({
523
530
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
524
531
  message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
525
532
  hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
@@ -542,18 +549,18 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
542
549
  let ctHashes;
543
550
  try {
544
551
  ctHashes = await publicClient.readContract({
545
- address: MocksZkVerifierAddress,
552
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
546
553
  abi: MockZkVerifierAbi,
547
554
  functionName: "zkVerifyCalcCtHashesPacked",
548
555
  args: calcCtHashesArgs
549
556
  });
550
557
  } catch (err) {
551
- throw new CofhesdkError({
558
+ throw new CofheError({
552
559
  code: "ZK_MOCKS_CALC_CT_HASHES_FAILED" /* ZkMocksCalcCtHashesFailed */,
553
560
  message: `mockZkVerifySign calcCtHashes failed while calling zkVerifyCalcCtHashesPacked`,
554
561
  cause: err instanceof Error ? err : void 0,
555
562
  context: {
556
- address: MocksZkVerifierAddress,
563
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
557
564
  items,
558
565
  account,
559
566
  securityZone,
@@ -563,7 +570,7 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
563
570
  });
564
571
  }
565
572
  if (ctHashes.length !== items.length) {
566
- throw new CofhesdkError({
573
+ throw new CofheError({
567
574
  code: "ZK_MOCKS_CALC_CT_HASHES_FAILED" /* ZkMocksCalcCtHashesFailed */,
568
575
  message: `mockZkVerifySign calcCtHashes returned incorrect number of ctHashes`,
569
576
  context: {
@@ -586,7 +593,7 @@ async function insertCtHashes(items, walletClient) {
586
593
  try {
587
594
  const account = walletClient.account;
588
595
  await walletClient.writeContract({
589
- address: MocksZkVerifierAddress,
596
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
590
597
  abi: MockZkVerifierAbi,
591
598
  functionName: "insertPackedCtHashes",
592
599
  args: insertPackedCtHashesArgs,
@@ -594,7 +601,7 @@ async function insertCtHashes(items, walletClient) {
594
601
  account
595
602
  });
596
603
  } catch (err) {
597
- throw new CofhesdkError({
604
+ throw new CofheError({
598
605
  code: "ZK_MOCKS_INSERT_CT_HASHES_FAILED" /* ZkMocksInsertCtHashesFailed */,
599
606
  message: `mockZkVerifySign insertPackedCtHashes failed while calling insertPackedCtHashes`,
600
607
  cause: err instanceof Error ? err : void 0,
@@ -612,7 +619,7 @@ async function createProofSignatures(items, securityZone) {
612
619
  try {
613
620
  encInputSignerClient = createMockZkVerifierSigner();
614
621
  } catch (err) {
615
- throw new CofhesdkError({
622
+ throw new CofheError({
616
623
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
617
624
  message: `mockZkVerifySign createProofSignatures failed while creating wallet client`,
618
625
  cause: err instanceof Error ? err : void 0,
@@ -633,7 +640,7 @@ async function createProofSignatures(items, securityZone) {
633
640
  signatures.push(signature);
634
641
  }
635
642
  } catch (err) {
636
- throw new CofhesdkError({
643
+ throw new CofheError({
637
644
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
638
645
  message: `mockZkVerifySign createProofSignatures failed while calling signMessage`,
639
646
  cause: err instanceof Error ? err : void 0,
@@ -644,7 +651,7 @@ async function createProofSignatures(items, securityZone) {
644
651
  });
645
652
  }
646
653
  if (signatures.length !== items.length) {
647
- throw new CofhesdkError({
654
+ throw new CofheError({
648
655
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
649
656
  message: `mockZkVerifySign createProofSignatures returned incorrect number of signatures`,
650
657
  context: {
@@ -674,21 +681,18 @@ var CofheChainSchema = zod.z.object({
674
681
  /** Network identifier */
675
682
  network: zod.z.string().min(1),
676
683
  /** coFhe service URL */
677
- coFheUrl: zod.z.string().url(),
684
+ coFheUrl: zod.z.url(),
678
685
  /** Verifier service URL */
679
- verifierUrl: zod.z.string().url(),
686
+ verifierUrl: zod.z.url(),
680
687
  /** Threshold network service URL */
681
- thresholdNetworkUrl: zod.z.string().url(),
688
+ thresholdNetworkUrl: zod.z.url(),
682
689
  /** Environment type */
683
690
  environment: EnvironmentSchema
684
691
  });
685
-
686
- // chains/defineChain.ts
687
692
  function defineChain(chainConfig) {
688
693
  const result = CofheChainSchema.safeParse(chainConfig);
689
694
  if (!result.success) {
690
- const errorMessages = result.error.errors.map((err) => `${err.path.join(".")}: ${err.message}`);
691
- throw new Error(`Invalid chain configuration: ${errorMessages.join(", ")}`);
695
+ throw new Error(`Invalid chain configuration: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
692
696
  }
693
697
  return result.data;
694
698
  }
@@ -704,43 +708,48 @@ var hardhat2 = defineChain({
704
708
  thresholdNetworkUrl: "http://127.0.0.1:3000",
705
709
  environment: "MOCK"
706
710
  });
707
- var CofhesdkConfigSchema = zod.z.object({
711
+ var CofheConfigSchema = zod.z.object({
708
712
  /** Environment that the SDK is running in */
709
713
  environment: zod.z.enum(["node", "hardhat", "web", "react"]).optional().default("node"),
710
714
  /** List of supported chain configurations */
711
715
  supportedChains: zod.z.array(zod.z.custom()),
712
- /** How permits are generated */
713
- permitGeneration: zod.z.enum(["ON_CONNECT", "ON_DECRYPT_HANDLES", "MANUAL"]).optional().default("ON_CONNECT"),
714
716
  /** Default permit expiration in seconds, default is 30 days */
715
717
  defaultPermitExpiration: zod.z.number().optional().default(60 * 60 * 24 * 30),
716
718
  /** Storage method for fhe keys (defaults to indexedDB on web, filesystem on node) */
717
719
  fheKeyStorage: zod.z.object({
718
- getItem: zod.z.function().args(zod.z.string()).returns(zod.z.promise(zod.z.any())),
719
- setItem: zod.z.function().args(zod.z.string(), zod.z.any()).returns(zod.z.promise(zod.z.void())),
720
- removeItem: zod.z.function().args(zod.z.string()).returns(zod.z.promise(zod.z.void()))
720
+ getItem: zod.z.custom((val) => typeof val === "function", {
721
+ message: "getItem must be a function"
722
+ }),
723
+ setItem: zod.z.custom((val) => typeof val === "function", {
724
+ message: "setItem must be a function"
725
+ }),
726
+ removeItem: zod.z.custom((val) => typeof val === "function", {
727
+ message: "removeItem must be a function"
728
+ })
721
729
  }).or(zod.z.null()).default(null),
722
730
  /** Whether to use Web Workers for ZK proof generation (web platform only) */
723
731
  useWorkers: zod.z.boolean().optional().default(true),
724
732
  /** Mocks configs */
725
733
  mocks: zod.z.object({
726
- sealOutputDelay: zod.z.number().optional().default(0)
727
- }).optional().default({ sealOutputDelay: 0 }),
734
+ decryptDelay: zod.z.number().optional().default(0),
735
+ 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])
736
+ }).optional().default({ decryptDelay: 0, encryptDelay: [100, 100, 100, 500, 500] }),
728
737
  /** Internal configuration */
729
738
  _internal: zod.z.object({
730
739
  zkvWalletClient: zod.z.any().optional()
731
740
  }).optional()
732
741
  });
733
- function createCofhesdkConfigBase(config) {
734
- const result = CofhesdkConfigSchema.safeParse(config);
742
+ function createCofheConfigBase(config) {
743
+ const result = CofheConfigSchema.safeParse(config);
735
744
  if (!result.success) {
736
- throw new Error(`Invalid cofhesdk configuration: ${result.error.message}`);
745
+ throw new Error(`Invalid cofhe configuration: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
737
746
  }
738
747
  return result.data;
739
748
  }
740
749
  function getSupportedChainOrThrow(config, chainId) {
741
750
  const supportedChain = config.supportedChains.find((chain) => chain.id === chainId);
742
751
  if (!supportedChain) {
743
- throw new CofhesdkError({
752
+ throw new CofheError({
744
753
  code: "UNSUPPORTED_CHAIN" /* UnsupportedChain */,
745
754
  message: `Config does not support chain <${chainId}>`,
746
755
  hint: "Ensure config passed to client has been created with this chain in the config.supportedChains array.",
@@ -756,7 +765,7 @@ function getCoFheUrlOrThrow(config, chainId) {
756
765
  const supportedChain = getSupportedChainOrThrow(config, chainId);
757
766
  const url = supportedChain.coFheUrl;
758
767
  if (!url) {
759
- throw new CofhesdkError({
768
+ throw new CofheError({
760
769
  code: "MISSING_CONFIG" /* MissingConfig */,
761
770
  message: `CoFHE URL is not configured for chain <${chainId}>`,
762
771
  hint: "Ensure this chain config includes a coFheUrl property.",
@@ -769,7 +778,7 @@ function getZkVerifierUrlOrThrow(config, chainId) {
769
778
  const supportedChain = getSupportedChainOrThrow(config, chainId);
770
779
  const url = supportedChain.verifierUrl;
771
780
  if (!url) {
772
- throw new CofhesdkError({
781
+ throw new CofheError({
773
782
  code: "ZK_VERIFIER_URL_UNINITIALIZED" /* ZkVerifierUrlUninitialized */,
774
783
  message: `ZK verifier URL is not configured for chain <${chainId}>`,
775
784
  hint: "Ensure this chain config includes a verifierUrl property.",
@@ -782,7 +791,7 @@ function getThresholdNetworkUrlOrThrow(config, chainId) {
782
791
  const supportedChain = getSupportedChainOrThrow(config, chainId);
783
792
  const url = supportedChain.thresholdNetworkUrl;
784
793
  if (!url) {
785
- throw new CofhesdkError({
794
+ throw new CofheError({
786
795
  code: "THRESHOLD_NETWORK_URL_UNINITIALIZED" /* ThresholdNetworkUrlUninitialized */,
787
796
  message: `Threshold network URL is not configured for chain <${chainId}>`,
788
797
  hint: "Ensure this chain config includes a thresholdNetworkUrl property.",
@@ -994,7 +1003,7 @@ var BaseBuilder = class {
994
1003
  account;
995
1004
  constructor(params) {
996
1005
  if (!params.config) {
997
- throw new CofhesdkError({
1006
+ throw new CofheError({
998
1007
  code: "MISSING_CONFIG" /* MissingConfig */,
999
1008
  message: "Builder config is undefined",
1000
1009
  hint: "Ensure client has been created with a config.",
@@ -1012,12 +1021,12 @@ var BaseBuilder = class {
1012
1021
  }
1013
1022
  /**
1014
1023
  * Asserts that this.chainId is populated
1015
- * @throws {CofhesdkError} If chainId is not set
1024
+ * @throws {CofheError} If chainId is not set
1016
1025
  */
1017
1026
  assertChainId() {
1018
1027
  if (this.chainId)
1019
1028
  return;
1020
- throw new CofhesdkError({
1029
+ throw new CofheError({
1021
1030
  code: "CHAIN_ID_UNINITIALIZED" /* ChainIdUninitialized */,
1022
1031
  message: "Chain ID is not set",
1023
1032
  hint: "Ensure client.connect() has been called and awaited, or use setChainId(...) to set the chainId explicitly.",
@@ -1028,12 +1037,12 @@ var BaseBuilder = class {
1028
1037
  }
1029
1038
  /**
1030
1039
  * Asserts that this.account is populated
1031
- * @throws {CofhesdkError} If account is not set
1040
+ * @throws {CofheError} If account is not set
1032
1041
  */
1033
1042
  assertAccount() {
1034
1043
  if (this.account)
1035
1044
  return;
1036
- throw new CofhesdkError({
1045
+ throw new CofheError({
1037
1046
  code: "ACCOUNT_UNINITIALIZED" /* AccountUninitialized */,
1038
1047
  message: "Account is not set",
1039
1048
  hint: "Ensure client.connect() has been called and awaited, or use setAccount(...) to set the account explicitly.",
@@ -1044,12 +1053,12 @@ var BaseBuilder = class {
1044
1053
  }
1045
1054
  /**
1046
1055
  * Asserts that this.publicClient is populated
1047
- * @throws {CofhesdkError} If publicClient is not set
1056
+ * @throws {CofheError} If publicClient is not set
1048
1057
  */
1049
1058
  assertPublicClient() {
1050
1059
  if (this.publicClient)
1051
1060
  return;
1052
- throw new CofhesdkError({
1061
+ throw new CofheError({
1053
1062
  code: "MISSING_PUBLIC_CLIENT" /* MissingPublicClient */,
1054
1063
  message: "Public client not found",
1055
1064
  hint: "Ensure client.connect() has been called with a publicClient.",
@@ -1060,12 +1069,12 @@ var BaseBuilder = class {
1060
1069
  }
1061
1070
  /**
1062
1071
  * Asserts that this.walletClient is populated
1063
- * @throws {CofhesdkError} If walletClient is not set
1072
+ * @throws {CofheError} If walletClient is not set
1064
1073
  */
1065
1074
  assertWalletClient() {
1066
1075
  if (this.walletClient)
1067
1076
  return;
1068
- throw new CofhesdkError({
1077
+ throw new CofheError({
1069
1078
  code: "MISSING_WALLET_CLIENT" /* MissingWalletClient */,
1070
1079
  message: "Wallet client not found",
1071
1080
  hint: "Ensure client.connect() has been called with a walletClient.",
@@ -1110,7 +1119,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1110
1119
  this.securityZone = params.securityZone ?? 0;
1111
1120
  this.zkvWalletClient = params.zkvWalletClient;
1112
1121
  if (!params.tfhePublicKeyDeserializer) {
1113
- throw new CofhesdkError({
1122
+ throw new CofheError({
1114
1123
  code: "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER" /* MissingTfhePublicKeyDeserializer */,
1115
1124
  message: "EncryptInputsBuilder tfhePublicKeyDeserializer is undefined",
1116
1125
  hint: "Ensure client has been created with a tfhePublicKeyDeserializer.",
@@ -1121,7 +1130,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1121
1130
  }
1122
1131
  this.tfhePublicKeyDeserializer = params.tfhePublicKeyDeserializer;
1123
1132
  if (!params.compactPkeCrsDeserializer) {
1124
- throw new CofhesdkError({
1133
+ throw new CofheError({
1125
1134
  code: "MISSING_COMPACT_PKE_CRS_DESERIALIZER" /* MissingCompactPkeCrsDeserializer */,
1126
1135
  message: "EncryptInputsBuilder compactPkeCrsDeserializer is undefined",
1127
1136
  hint: "Ensure client has been created with a compactPkeCrsDeserializer.",
@@ -1132,7 +1141,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1132
1141
  }
1133
1142
  this.compactPkeCrsDeserializer = params.compactPkeCrsDeserializer;
1134
1143
  if (!params.zkBuilderAndCrsGenerator) {
1135
- throw new CofhesdkError({
1144
+ throw new CofheError({
1136
1145
  code: "MISSING_ZK_BUILDER_AND_CRS_GENERATOR" /* MissingZkBuilderAndCrsGenerator */,
1137
1146
  message: "EncryptInputsBuilder zkBuilderAndCrsGenerator is undefined",
1138
1147
  hint: "Ensure client has been created with a zkBuilderAndCrsGenerator.",
@@ -1156,7 +1165,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1156
1165
  * ```typescript
1157
1166
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1158
1167
  * .setAccount("0x123")
1159
- * .encrypt();
1168
+ * .execute();
1160
1169
  * ```
1161
1170
  *
1162
1171
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1177,7 +1186,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1177
1186
  * ```typescript
1178
1187
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1179
1188
  * .setChainId(11155111)
1180
- * .encrypt();
1189
+ * .execute();
1181
1190
  * ```
1182
1191
  *
1183
1192
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1198,7 +1207,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1198
1207
  * ```typescript
1199
1208
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1200
1209
  * .setSecurityZone(1)
1201
- * .encrypt();
1210
+ * .execute();
1202
1211
  * ```
1203
1212
  *
1204
1213
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1219,7 +1228,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1219
1228
  * ```typescript
1220
1229
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1221
1230
  * .setUseWorker(false)
1222
- * .encrypt();
1231
+ * .execute();
1223
1232
  * ```
1224
1233
  *
1225
1234
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1253,13 +1262,13 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1253
1262
  * Example:
1254
1263
  * ```typescript
1255
1264
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1256
- * .setStepCallback((step: EncryptStep) => console.log(step))
1257
- * .encrypt();
1265
+ * .onStep((step: EncryptStep) => console.log(step))
1266
+ * .execute();
1258
1267
  * ```
1259
1268
  *
1260
1269
  * @returns The EncryptInputsBuilder instance.
1261
1270
  */
1262
- setStepCallback(callback) {
1271
+ onStep(callback) {
1263
1272
  this.stepCallback = callback;
1264
1273
  return this;
1265
1274
  }
@@ -1282,7 +1291,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1282
1291
  this.stepCallback(step, { ...context, isStart: false, isEnd: true, duration });
1283
1292
  }
1284
1293
  /**
1285
- * zkVerifierUrl is included in the chains exported from cofhesdk/chains for use in CofhesdkConfig.supportedChains
1294
+ * zkVerifierUrl is included in the chains exported from @cofhe/sdk/chains for use in CofheConfig.supportedChains
1286
1295
  * Users should generally not set this manually.
1287
1296
  */
1288
1297
  async getZkVerifierUrl() {
@@ -1290,7 +1299,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1290
1299
  return getZkVerifierUrlOrThrow(this.config, this.chainId);
1291
1300
  }
1292
1301
  /**
1293
- * initTfhe is a platform-specific dependency injected into core/createCofhesdkClientBase by web/createCofhesdkClient and node/createCofhesdkClient
1302
+ * initTfhe is a platform-specific dependency injected into core/createCofheClientBase by web/createCofheClient and node/createCofheClient
1294
1303
  * web/ uses zama "tfhe"
1295
1304
  * node/ uses zama "node-tfhe"
1296
1305
  * Users should not set this manually.
@@ -1301,7 +1310,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1301
1310
  try {
1302
1311
  return await this.initTfhe();
1303
1312
  } catch (error) {
1304
- throw CofhesdkError.fromError(error, {
1313
+ throw CofheError.fromError(error, {
1305
1314
  code: "INIT_TFHE_FAILED" /* InitTfheFailed */,
1306
1315
  message: `Failed to initialize TFHE`,
1307
1316
  context: {
@@ -1320,7 +1329,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1320
1329
  try {
1321
1330
  await this.keysStorage?.rehydrateKeysStore();
1322
1331
  } catch (error) {
1323
- throw CofhesdkError.fromError(error, {
1332
+ throw CofheError.fromError(error, {
1324
1333
  code: "REHYDRATE_KEYS_STORE_FAILED" /* RehydrateKeysStoreFailed */,
1325
1334
  message: `Failed to rehydrate keys store`,
1326
1335
  context: {
@@ -1342,7 +1351,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1342
1351
  this.keysStorage
1343
1352
  );
1344
1353
  } catch (error) {
1345
- throw CofhesdkError.fromError(error, {
1354
+ throw CofheError.fromError(error, {
1346
1355
  code: "FETCH_KEYS_FAILED" /* FetchKeysFailed */,
1347
1356
  message: `Failed to fetch FHE key and CRS`,
1348
1357
  context: {
@@ -1355,7 +1364,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1355
1364
  });
1356
1365
  }
1357
1366
  if (!fheKey) {
1358
- throw new CofhesdkError({
1367
+ throw new CofheError({
1359
1368
  code: "MISSING_FHE_KEY" /* MissingFheKey */,
1360
1369
  message: `FHE key not found`,
1361
1370
  context: {
@@ -1365,7 +1374,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1365
1374
  });
1366
1375
  }
1367
1376
  if (!crs) {
1368
- throw new CofhesdkError({
1377
+ throw new CofheError({
1369
1378
  code: "MISSING_CRS" /* MissingCrs */,
1370
1379
  message: `CRS not found for chainId <${this.chainId}>`,
1371
1380
  context: {
@@ -1375,6 +1384,17 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1375
1384
  }
1376
1385
  return { fheKey, fheKeyFetchedFromCoFHE, crs, crsFetchedFromCoFHE };
1377
1386
  }
1387
+ /**
1388
+ * Resolves the encryptDelay config into an array of 5 per-step delays.
1389
+ * A single number is broadcast to all steps; a tuple is used as-is.
1390
+ */
1391
+ resolveEncryptDelays() {
1392
+ const encryptDelay = this.config?.mocks?.encryptDelay ?? [100, 100, 100, 500, 500];
1393
+ if (typeof encryptDelay === "number") {
1394
+ return [encryptDelay, encryptDelay, encryptDelay, encryptDelay, encryptDelay];
1395
+ }
1396
+ return encryptDelay;
1397
+ }
1378
1398
  /**
1379
1399
  * @dev Encrypt against the cofheMocks instead of CoFHE
1380
1400
  *
@@ -1382,25 +1402,35 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1382
1402
  * cofheMocksInsertPackedHashes - stores the ctHashes and their plaintext values for on-chain mocking of FHE operations.
1383
1403
  * cofheMocksZkCreateProofSignatures - creates signatures to be included in the encrypted inputs. The signers address is known and verified in the mock contracts.
1384
1404
  */
1385
- async mocksEncrypt() {
1405
+ async mocksExecute() {
1386
1406
  this.assertAccount();
1387
1407
  this.assertPublicClient();
1388
1408
  this.assertWalletClient();
1409
+ const [initTfheDelay, fetchKeysDelay, packDelay, proveDelay, verifyDelay] = this.resolveEncryptDelays();
1389
1410
  this.fireStepStart("initTfhe" /* InitTfhe */);
1390
- await sleep(100);
1391
- this.fireStepEnd("initTfhe" /* InitTfhe */, { tfheInitializationExecuted: false });
1411
+ await sleep(initTfheDelay);
1412
+ this.fireStepEnd("initTfhe" /* InitTfhe */, {
1413
+ tfheInitializationExecuted: false,
1414
+ isMocks: true,
1415
+ mockSleep: initTfheDelay
1416
+ });
1392
1417
  this.fireStepStart("fetchKeys" /* FetchKeys */);
1393
- await sleep(100);
1394
- this.fireStepEnd("fetchKeys" /* FetchKeys */, { fheKeyFetchedFromCoFHE: false, crsFetchedFromCoFHE: false });
1418
+ await sleep(fetchKeysDelay);
1419
+ this.fireStepEnd("fetchKeys" /* FetchKeys */, {
1420
+ fheKeyFetchedFromCoFHE: false,
1421
+ crsFetchedFromCoFHE: false,
1422
+ isMocks: true,
1423
+ mockSleep: fetchKeysDelay
1424
+ });
1395
1425
  this.fireStepStart("pack" /* Pack */);
1396
1426
  await cofheMocksCheckEncryptableBits(this.inputItems);
1397
- await sleep(100);
1398
- this.fireStepEnd("pack" /* Pack */);
1427
+ await sleep(packDelay);
1428
+ this.fireStepEnd("pack" /* Pack */, { isMocks: true, mockSleep: packDelay });
1399
1429
  this.fireStepStart("prove" /* Prove */);
1400
- await sleep(500);
1401
- this.fireStepEnd("prove" /* Prove */);
1430
+ await sleep(proveDelay);
1431
+ this.fireStepEnd("prove" /* Prove */, { isMocks: true, mockSleep: proveDelay });
1402
1432
  this.fireStepStart("verify" /* Verify */);
1403
- await sleep(500);
1433
+ await sleep(verifyDelay);
1404
1434
  const signedResults = await cofheMocksZkVerifySign(
1405
1435
  this.inputItems,
1406
1436
  this.account,
@@ -1415,13 +1445,13 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1415
1445
  utype: this.inputItems[index].utype,
1416
1446
  signature
1417
1447
  }));
1418
- this.fireStepEnd("verify" /* Verify */);
1448
+ this.fireStepEnd("verify" /* Verify */, { isMocks: true, mockSleep: verifyDelay });
1419
1449
  return encryptedInputs;
1420
1450
  }
1421
1451
  /**
1422
1452
  * In the production context, perform a true encryption with the CoFHE coprocessor.
1423
1453
  */
1424
- async productionEncrypt() {
1454
+ async productionExecute() {
1425
1455
  this.assertAccount();
1426
1456
  this.assertChainId();
1427
1457
  this.fireStepStart("initTfhe" /* InitTfhe */);
@@ -1484,15 +1514,15 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1484
1514
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1485
1515
  * .setAccount('0x123...890') // optional
1486
1516
  * .setChainId(11155111) // optional
1487
- * .encrypt(); // execute
1517
+ * .execute(); // execute
1488
1518
  * ```
1489
1519
  *
1490
1520
  * @returns The encrypted inputs.
1491
1521
  */
1492
- async encrypt() {
1522
+ async execute() {
1493
1523
  if (this.chainId === chains.hardhat.id)
1494
- return this.mocksEncrypt();
1495
- return this.productionEncrypt();
1524
+ return this.mocksExecute();
1525
+ return this.productionExecute();
1496
1526
  }
1497
1527
  };
1498
1528
 
@@ -1543,9 +1573,6 @@ function isBigIntOrNumber(value) {
1543
1573
  }
1544
1574
  }
1545
1575
  }
1546
- function is0xPrefixed(value) {
1547
- return value.startsWith("0x");
1548
- }
1549
1576
 
1550
1577
  // permits/sealing.ts
1551
1578
  var PRIVATE_KEY_LENGTH = 64;
@@ -1633,158 +1660,137 @@ var SerializedSealingPair = zod.z.object({
1633
1660
  privateKey: zod.z.string(),
1634
1661
  publicKey: zod.z.string()
1635
1662
  });
1663
+ var addressSchema = zod.z.string().refine((val) => viem.isAddress(val), {
1664
+ error: "Invalid address"
1665
+ }).transform((val) => viem.getAddress(val));
1666
+ var addressNotZeroSchema = addressSchema.refine((val) => val !== viem.zeroAddress, {
1667
+ error: "Must not be zeroAddress"
1668
+ });
1669
+ var bytesSchema = zod.z.custom(
1670
+ (val) => {
1671
+ return typeof val === "string" && viem.isHex(val);
1672
+ },
1673
+ {
1674
+ message: "Invalid hex value"
1675
+ }
1676
+ );
1677
+ var bytesNotEmptySchema = bytesSchema.refine((val) => val !== "0x", {
1678
+ error: "Must not be empty"
1679
+ });
1636
1680
  var DEFAULT_EXPIRATION_FN = () => Math.round(Date.now() / 1e3) + 7 * 24 * 60 * 60;
1637
1681
  var zPermitWithDefaults = zod.z.object({
1638
1682
  name: zod.z.string().optional().default("Unnamed Permit"),
1639
1683
  type: zod.z.enum(["self", "sharing", "recipient"]),
1640
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1641
- message: "Permit issuer :: invalid address"
1642
- }).refine((val) => val !== viem.zeroAddress, {
1643
- message: "Permit issuer :: must not be zeroAddress"
1644
- }),
1645
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1646
- recipient: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1647
- message: "Permit recipient :: invalid address"
1648
- }),
1649
- validatorId: zod.z.number().optional().default(0),
1650
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1651
- message: "Permit validatorContract :: invalid address"
1652
- }),
1653
- issuerSignature: zod.z.string().optional().default("0x"),
1654
- recipientSignature: zod.z.string().optional().default("0x")
1684
+ issuer: addressNotZeroSchema,
1685
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1686
+ recipient: addressSchema.optional().default(viem.zeroAddress),
1687
+ validatorId: zod.z.int().optional().default(0),
1688
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1689
+ issuerSignature: bytesSchema.optional().default("0x"),
1690
+ recipientSignature: bytesSchema.optional().default("0x")
1655
1691
  });
1656
1692
  var zPermitWithSealingPair = zPermitWithDefaults.extend({
1657
1693
  sealingPair: SerializedSealingPair.optional()
1658
1694
  });
1659
- var ValidatorContractRefinement = [
1695
+ var ExternalValidatorRefinement = [
1660
1696
  (data) => data.validatorId !== 0 && data.validatorContract !== viem.zeroAddress || data.validatorId === 0 && data.validatorContract === viem.zeroAddress,
1661
1697
  {
1662
- message: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
1698
+ error: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
1663
1699
  path: ["validatorId", "validatorContract"]
1664
1700
  }
1665
1701
  ];
1702
+ var RecipientRefinement = [
1703
+ (data) => data.issuer !== data.recipient,
1704
+ {
1705
+ error: "Sharing permit :: issuer and recipient must not be the same",
1706
+ path: ["issuer", "recipient"]
1707
+ }
1708
+ ];
1666
1709
  var SelfPermitOptionsValidator = zod.z.object({
1667
1710
  type: zod.z.literal("self").optional().default("self"),
1668
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1669
- message: "Self permit issuer :: invalid address"
1670
- }).refine((val) => is0xPrefixed(val), {
1671
- message: "Self permit issuer :: must be 0x prefixed"
1672
- }).refine((val) => val !== viem.zeroAddress, {
1673
- message: "Self permit issuer :: must not be zeroAddress"
1674
- }),
1711
+ issuer: addressNotZeroSchema,
1675
1712
  name: zod.z.string().optional().default("Unnamed Permit"),
1676
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1677
- recipient: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1678
- message: "Self permit recipient :: invalid address"
1679
- }).refine((val) => is0xPrefixed(val), {
1680
- message: "Self permit recipient :: must be 0x prefixed"
1681
- }).refine((val) => val === viem.zeroAddress, {
1682
- message: "Self permit recipient :: must be zeroAddress"
1683
- }),
1684
- validatorId: zod.z.number().optional().default(0),
1685
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1686
- message: "Self permit validatorContract :: invalid address"
1687
- }),
1688
- issuerSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1689
- message: "Self permit issuerSignature :: must be 0x prefixed"
1690
- }),
1691
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1692
- message: "Self permit recipientSignature :: must be 0x prefixed"
1693
- })
1694
- }).refine(...ValidatorContractRefinement);
1713
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1714
+ recipient: addressSchema.optional().default(viem.zeroAddress),
1715
+ validatorId: zod.z.int().optional().default(0),
1716
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1717
+ issuerSignature: bytesSchema.optional().default("0x"),
1718
+ recipientSignature: bytesSchema.optional().default("0x")
1719
+ }).refine(...ExternalValidatorRefinement);
1695
1720
  var SelfPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "self", {
1696
- message: "Self permit :: type must be 'self'"
1721
+ error: "Type must be 'self'"
1697
1722
  }).refine((data) => data.recipient === viem.zeroAddress, {
1698
- message: "Self permit :: recipient must be zeroAddress"
1723
+ error: "Recipient must be zeroAddress"
1699
1724
  }).refine((data) => data.issuerSignature !== "0x", {
1700
- message: "Self permit :: issuerSignature must be populated"
1725
+ error: "IssuerSignature must be populated"
1701
1726
  }).refine((data) => data.recipientSignature === "0x", {
1702
- message: "Self permit :: recipientSignature must be empty"
1703
- }).refine(...ValidatorContractRefinement);
1727
+ error: "RecipientSignature must be empty"
1728
+ }).refine(...ExternalValidatorRefinement);
1704
1729
  var SharingPermitOptionsValidator = zod.z.object({
1705
1730
  type: zod.z.literal("sharing").optional().default("sharing"),
1706
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1707
- message: "Sharing permit issuer :: invalid address"
1708
- }).refine((val) => is0xPrefixed(val), {
1709
- message: "Sharing permit issuer :: must be 0x prefixed"
1710
- }).refine((val) => val !== viem.zeroAddress, {
1711
- message: "Sharing permit issuer :: must not be zeroAddress"
1712
- }),
1713
- recipient: zod.z.string().refine((val) => viem.isAddress(val), {
1714
- message: "Sharing permit recipient :: invalid address"
1715
- }).refine((val) => is0xPrefixed(val), {
1716
- message: "Sharing permit recipient :: must be 0x prefixed"
1717
- }).refine((val) => val !== viem.zeroAddress, {
1718
- message: "Sharing permit recipient :: must not be zeroAddress"
1719
- }),
1731
+ issuer: addressNotZeroSchema,
1732
+ recipient: addressNotZeroSchema,
1720
1733
  name: zod.z.string().optional().default("Unnamed Permit"),
1721
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1722
- validatorId: zod.z.number().optional().default(0),
1723
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1724
- message: "Sharing permit validatorContract :: invalid address"
1725
- }),
1726
- issuerSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1727
- message: "Sharing permit issuerSignature :: must be 0x prefixed"
1728
- }),
1729
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1730
- message: "Sharing permit recipientSignature :: must be 0x prefixed"
1731
- })
1732
- }).refine(...ValidatorContractRefinement);
1734
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1735
+ validatorId: zod.z.int().optional().default(0),
1736
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1737
+ issuerSignature: bytesSchema.optional().default("0x"),
1738
+ recipientSignature: bytesSchema.optional().default("0x")
1739
+ }).refine(...RecipientRefinement).refine(...ExternalValidatorRefinement);
1733
1740
  var SharingPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "sharing", {
1734
- message: "Sharing permit :: type must be 'sharing'"
1741
+ error: "Type must be 'sharing'"
1735
1742
  }).refine((data) => data.recipient !== viem.zeroAddress, {
1736
- message: "Sharing permit :: recipient must not be zeroAddress"
1743
+ error: "Recipient must not be zeroAddress"
1737
1744
  }).refine((data) => data.issuerSignature !== "0x", {
1738
- message: "Sharing permit :: issuerSignature must be populated"
1745
+ error: "IssuerSignature must be populated"
1739
1746
  }).refine((data) => data.recipientSignature === "0x", {
1740
- message: "Sharing permit :: recipientSignature must be empty"
1741
- }).refine(...ValidatorContractRefinement);
1747
+ error: "RecipientSignature must be empty"
1748
+ }).refine(...ExternalValidatorRefinement);
1742
1749
  var ImportPermitOptionsValidator = zod.z.object({
1743
1750
  type: zod.z.literal("recipient").optional().default("recipient"),
1744
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1745
- message: "Import permit issuer :: invalid address"
1746
- }).refine((val) => is0xPrefixed(val), {
1747
- message: "Import permit issuer :: must be 0x prefixed"
1748
- }).refine((val) => val !== viem.zeroAddress, {
1749
- message: "Import permit issuer :: must not be zeroAddress"
1750
- }),
1751
- recipient: zod.z.string().refine((val) => viem.isAddress(val), {
1752
- message: "Import permit recipient :: invalid address"
1753
- }).refine((val) => is0xPrefixed(val), {
1754
- message: "Import permit recipient :: must be 0x prefixed"
1755
- }).refine((val) => val !== viem.zeroAddress, {
1756
- message: "Import permit recipient :: must not be zeroAddress"
1757
- }),
1758
- issuerSignature: zod.z.string().refine((val) => is0xPrefixed(val), {
1759
- message: "Import permit issuerSignature :: must be 0x prefixed"
1760
- }).refine((val) => val !== "0x", {
1761
- message: "Import permit :: issuerSignature must be provided"
1762
- }),
1751
+ issuer: addressNotZeroSchema,
1752
+ recipient: addressNotZeroSchema,
1763
1753
  name: zod.z.string().optional().default("Unnamed Permit"),
1764
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1765
- validatorId: zod.z.number().optional().default(0),
1766
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1767
- message: "Import permit validatorContract :: invalid address"
1768
- }),
1769
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1770
- message: "Import permit recipientSignature :: must be 0x prefixed"
1771
- })
1772
- }).refine(...ValidatorContractRefinement);
1754
+ expiration: zod.z.int(),
1755
+ validatorId: zod.z.int().optional().default(0),
1756
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1757
+ issuerSignature: bytesNotEmptySchema,
1758
+ recipientSignature: bytesSchema.optional().default("0x")
1759
+ }).refine(...ExternalValidatorRefinement);
1773
1760
  var ImportPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "recipient", {
1774
- message: "Import permit :: type must be 'recipient'"
1761
+ error: "Type must be 'recipient'"
1775
1762
  }).refine((data) => data.recipient !== viem.zeroAddress, {
1776
- message: "Import permit :: recipient must not be zeroAddress"
1763
+ error: "Recipient must not be zeroAddress"
1777
1764
  }).refine((data) => data.issuerSignature !== "0x", {
1778
- message: "Import permit :: issuerSignature must be populated"
1765
+ error: "IssuerSignature must be populated"
1779
1766
  }).refine((data) => data.recipientSignature !== "0x", {
1780
- message: "Import permit :: recipientSignature must be populated"
1781
- }).refine(...ValidatorContractRefinement);
1782
- var validateSelfPermitOptions = (options) => SelfPermitOptionsValidator.safeParse(options);
1783
- var validateSharingPermitOptions = (options) => SharingPermitOptionsValidator.safeParse(options);
1784
- var validateImportPermitOptions = (options) => ImportPermitOptionsValidator.safeParse(options);
1785
- var validateSelfPermit = (permit) => SelfPermitValidator.safeParse(permit);
1786
- var validateSharingPermit = (permit) => SharingPermitValidator.safeParse(permit);
1787
- var validateImportPermit = (permit) => ImportPermitValidator.safeParse(permit);
1767
+ error: "RecipientSignature must be populated"
1768
+ }).refine(...ExternalValidatorRefinement);
1769
+ var safeParseAndThrowFormatted = (schema, data, message) => {
1770
+ const result = schema.safeParse(data);
1771
+ if (!result.success) {
1772
+ throw new Error(`${message}: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
1773
+ }
1774
+ return result.data;
1775
+ };
1776
+ var validateSelfPermitOptions = (options) => {
1777
+ return safeParseAndThrowFormatted(SelfPermitOptionsValidator, options, "Invalid self permit options");
1778
+ };
1779
+ var validateSharingPermitOptions = (options) => {
1780
+ return safeParseAndThrowFormatted(SharingPermitOptionsValidator, options, "Invalid sharing permit options");
1781
+ };
1782
+ var validateImportPermitOptions = (options) => {
1783
+ return safeParseAndThrowFormatted(ImportPermitOptionsValidator, options, "Invalid import permit options");
1784
+ };
1785
+ var validateSelfPermit = (permit) => {
1786
+ return safeParseAndThrowFormatted(SelfPermitValidator, permit, "Invalid self permit");
1787
+ };
1788
+ var validateSharingPermit = (permit) => {
1789
+ return safeParseAndThrowFormatted(SharingPermitValidator, permit, "Invalid sharing permit");
1790
+ };
1791
+ var validateImportPermit = (permit) => {
1792
+ return safeParseAndThrowFormatted(ImportPermitValidator, permit, "Invalid import permit");
1793
+ };
1788
1794
  var ValidationUtils = {
1789
1795
  /**
1790
1796
  * Check if permit is expired
@@ -1878,6 +1884,179 @@ var SignatureUtils = {
1878
1884
  throw new Error(`Unknown permit type: ${permitType}`);
1879
1885
  }
1880
1886
  };
1887
+ var getAclAddress = async (publicClient) => {
1888
+ const ACL_IFACE = "function acl() view returns (address)";
1889
+ const aclAbi = viem.parseAbi([ACL_IFACE]);
1890
+ return await publicClient.readContract({
1891
+ address: TASK_MANAGER_ADDRESS,
1892
+ abi: aclAbi,
1893
+ functionName: "acl"
1894
+ });
1895
+ };
1896
+ var getAclEIP712Domain = async (publicClient) => {
1897
+ const aclAddress = await getAclAddress(publicClient);
1898
+ const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
1899
+ const domainAbi = viem.parseAbi([EIP712_DOMAIN_IFACE]);
1900
+ const domain = await publicClient.readContract({
1901
+ address: aclAddress,
1902
+ abi: domainAbi,
1903
+ functionName: "eip712Domain"
1904
+ });
1905
+ const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
1906
+ return {
1907
+ name,
1908
+ version,
1909
+ chainId: Number(chainId),
1910
+ verifyingContract
1911
+ };
1912
+ };
1913
+ var checkPermitValidityOnChain = async (permission, publicClient) => {
1914
+ const aclAddress = await getAclAddress(publicClient);
1915
+ try {
1916
+ await publicClient.simulateContract({
1917
+ address: aclAddress,
1918
+ abi: checkPermitValidityAbi,
1919
+ functionName: "checkPermitValidity",
1920
+ args: [
1921
+ {
1922
+ issuer: permission.issuer,
1923
+ expiration: BigInt(permission.expiration),
1924
+ recipient: permission.recipient,
1925
+ validatorId: BigInt(permission.validatorId),
1926
+ validatorContract: permission.validatorContract,
1927
+ sealingKey: permission.sealingKey,
1928
+ issuerSignature: permission.issuerSignature,
1929
+ recipientSignature: permission.recipientSignature
1930
+ }
1931
+ ]
1932
+ });
1933
+ return true;
1934
+ } catch (err) {
1935
+ if (err instanceof viem.BaseError) {
1936
+ const revertError = err.walk((err2) => err2 instanceof viem.ContractFunctionRevertedError);
1937
+ if (revertError instanceof viem.ContractFunctionRevertedError) {
1938
+ const errorName = revertError.data?.errorName ?? "";
1939
+ throw new Error(errorName);
1940
+ }
1941
+ }
1942
+ const customErrorName = extractCustomErrorFromDetails(err, checkPermitValidityAbi);
1943
+ if (customErrorName) {
1944
+ throw new Error(customErrorName);
1945
+ }
1946
+ const hhDetailsData = extractReturnData(err);
1947
+ if (hhDetailsData != null) {
1948
+ const decoded = viem.decodeErrorResult({
1949
+ abi: checkPermitValidityAbi,
1950
+ data: hhDetailsData
1951
+ });
1952
+ throw new Error(decoded.errorName);
1953
+ }
1954
+ throw err;
1955
+ }
1956
+ };
1957
+ function extractCustomErrorFromDetails(err, abi) {
1958
+ const anyErr = err;
1959
+ const details = anyErr?.details ?? anyErr?.cause?.details;
1960
+ if (typeof details === "string") {
1961
+ const customErrorMatch = details.match(/reverted with custom error '(\w+)\(\)'/);
1962
+ if (customErrorMatch) {
1963
+ const errorName = customErrorMatch[1];
1964
+ const errorExists = abi.some((item) => item.type === "error" && item.name === errorName);
1965
+ if (errorExists) {
1966
+ return errorName;
1967
+ }
1968
+ }
1969
+ }
1970
+ return void 0;
1971
+ }
1972
+ function extractReturnData(err) {
1973
+ const anyErr = err;
1974
+ const s = anyErr?.details ?? anyErr?.cause?.details ?? anyErr?.shortMessage ?? anyErr?.message ?? String(err);
1975
+ return s.match(/return data:\s*(0x[a-fA-F0-9]+)/)?.[1];
1976
+ }
1977
+ var checkPermitValidityAbi = [
1978
+ {
1979
+ type: "function",
1980
+ name: "checkPermitValidity",
1981
+ inputs: [
1982
+ {
1983
+ name: "permission",
1984
+ type: "tuple",
1985
+ internalType: "struct Permission",
1986
+ components: [
1987
+ {
1988
+ name: "issuer",
1989
+ type: "address",
1990
+ internalType: "address"
1991
+ },
1992
+ {
1993
+ name: "expiration",
1994
+ type: "uint64",
1995
+ internalType: "uint64"
1996
+ },
1997
+ {
1998
+ name: "recipient",
1999
+ type: "address",
2000
+ internalType: "address"
2001
+ },
2002
+ {
2003
+ name: "validatorId",
2004
+ type: "uint256",
2005
+ internalType: "uint256"
2006
+ },
2007
+ {
2008
+ name: "validatorContract",
2009
+ type: "address",
2010
+ internalType: "address"
2011
+ },
2012
+ {
2013
+ name: "sealingKey",
2014
+ type: "bytes32",
2015
+ internalType: "bytes32"
2016
+ },
2017
+ {
2018
+ name: "issuerSignature",
2019
+ type: "bytes",
2020
+ internalType: "bytes"
2021
+ },
2022
+ {
2023
+ name: "recipientSignature",
2024
+ type: "bytes",
2025
+ internalType: "bytes"
2026
+ }
2027
+ ]
2028
+ }
2029
+ ],
2030
+ outputs: [
2031
+ {
2032
+ name: "",
2033
+ type: "bool",
2034
+ internalType: "bool"
2035
+ }
2036
+ ],
2037
+ stateMutability: "view"
2038
+ },
2039
+ {
2040
+ type: "error",
2041
+ name: "PermissionInvalid_Disabled",
2042
+ inputs: []
2043
+ },
2044
+ {
2045
+ type: "error",
2046
+ name: "PermissionInvalid_Expired",
2047
+ inputs: []
2048
+ },
2049
+ {
2050
+ type: "error",
2051
+ name: "PermissionInvalid_IssuerSignature",
2052
+ inputs: []
2053
+ },
2054
+ {
2055
+ type: "error",
2056
+ name: "PermissionInvalid_RecipientSignature",
2057
+ inputs: []
2058
+ }
2059
+ ];
1881
2060
 
1882
2061
  // permits/permit.ts
1883
2062
  var PermitUtils = {
@@ -1886,14 +2065,10 @@ var PermitUtils = {
1886
2065
  */
1887
2066
  createSelf: (options) => {
1888
2067
  const validation = validateSelfPermitOptions(options);
1889
- if (!validation.success) {
1890
- throw new Error(
1891
- "PermitUtils :: createSelf :: Parsing SelfPermitOptions failed " + JSON.stringify(validation.error, null, 2)
1892
- );
1893
- }
1894
2068
  const sealingPair = GenerateSealingKey();
1895
2069
  const permit = {
1896
- ...validation.data,
2070
+ hash: PermitUtils.getHash(validation),
2071
+ ...validation,
1897
2072
  sealingPair,
1898
2073
  _signedDomain: void 0
1899
2074
  };
@@ -1904,14 +2079,10 @@ var PermitUtils = {
1904
2079
  */
1905
2080
  createSharing: (options) => {
1906
2081
  const validation = validateSharingPermitOptions(options);
1907
- if (!validation.success) {
1908
- throw new Error(
1909
- "PermitUtils :: createSharing :: Parsing SharingPermitOptions failed " + JSON.stringify(validation.error, null, 2)
1910
- );
1911
- }
1912
2082
  const sealingPair = GenerateSealingKey();
1913
2083
  const permit = {
1914
- ...validation.data,
2084
+ hash: PermitUtils.getHash(validation),
2085
+ ...validation,
1915
2086
  sealingPair,
1916
2087
  _signedDomain: void 0
1917
2088
  };
@@ -1926,27 +2097,21 @@ var PermitUtils = {
1926
2097
  try {
1927
2098
  parsedOptions = JSON.parse(options);
1928
2099
  } catch (error) {
1929
- throw new Error(`PermitUtils :: importShared :: Failed to parse JSON string: ${error}`);
2100
+ throw new Error(`Failed to parse JSON string: ${error}`);
1930
2101
  }
1931
2102
  } else if (typeof options === "object" && options !== null) {
1932
2103
  parsedOptions = options;
1933
2104
  } else {
1934
- throw new Error(
1935
- "PermitUtils :: importShared :: Invalid input type, expected ImportSharedPermitOptions, object, or string"
1936
- );
2105
+ throw new Error("Invalid input type, expected ImportSharedPermitOptions, object, or string");
1937
2106
  }
1938
2107
  if (parsedOptions.type != null && parsedOptions.type !== "sharing") {
1939
- throw new Error(`PermitUtils :: importShared :: Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
2108
+ throw new Error(`Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
1940
2109
  }
1941
2110
  const validation = validateImportPermitOptions({ ...parsedOptions, type: "recipient" });
1942
- if (!validation.success) {
1943
- throw new Error(
1944
- "PermitUtils :: importShared :: Parsing ImportPermitOptions failed " + JSON.stringify(validation.error, null, 2)
1945
- );
1946
- }
1947
2111
  const sealingPair = GenerateSealingKey();
1948
2112
  const permit = {
1949
- ...validation.data,
2113
+ hash: PermitUtils.getHash(validation),
2114
+ ...validation,
1950
2115
  sealingPair,
1951
2116
  _signedDomain: void 0
1952
2117
  };
@@ -1958,11 +2123,11 @@ var PermitUtils = {
1958
2123
  sign: async (permit, publicClient, walletClient) => {
1959
2124
  if (walletClient == null || walletClient.account == null) {
1960
2125
  throw new Error(
1961
- "PermitUtils :: sign - walletClient undefined, you must pass in a `walletClient` for the connected user to create a permit signature"
2126
+ "Missing walletClient, you must pass in a `walletClient` for the connected user to create a permit signature"
1962
2127
  );
1963
2128
  }
1964
2129
  const primaryType = SignatureUtils.getPrimaryType(permit.type);
1965
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
2130
+ const domain = await getAclEIP712Domain(publicClient);
1966
2131
  const { types, message } = SignatureUtils.getSignatureParams(PermitUtils.getPermission(permit, true), primaryType);
1967
2132
  const signature = await walletClient.signTypedData({
1968
2133
  domain,
@@ -2022,6 +2187,7 @@ var PermitUtils = {
2022
2187
  */
2023
2188
  serialize: (permit) => {
2024
2189
  return {
2190
+ hash: permit.hash,
2025
2191
  name: permit.name,
2026
2192
  type: permit.type,
2027
2193
  issuer: permit.issuer,
@@ -2046,7 +2212,7 @@ var PermitUtils = {
2046
2212
  } else if (permit.type === "recipient") {
2047
2213
  return validateImportPermit(permit);
2048
2214
  } else {
2049
- throw new Error("PermitUtils :: validate :: Invalid permit type");
2215
+ throw new Error("Invalid permit type");
2050
2216
  }
2051
2217
  },
2052
2218
  /**
@@ -2054,12 +2220,7 @@ var PermitUtils = {
2054
2220
  */
2055
2221
  getPermission: (permit, skipValidation = false) => {
2056
2222
  if (!skipValidation) {
2057
- const validationResult = PermitUtils.validate(permit);
2058
- if (!validationResult.success) {
2059
- throw new Error(
2060
- `PermitUtils :: getPermission :: permit validation failed - ${JSON.stringify(validationResult.error, null, 2)} ${JSON.stringify(permit, null, 2)}`
2061
- );
2062
- }
2223
+ PermitUtils.validate(permit);
2063
2224
  }
2064
2225
  return {
2065
2226
  issuer: permit.issuer,
@@ -2140,28 +2301,7 @@ var PermitUtils = {
2140
2301
  * Fetch EIP712 domain from the blockchain
2141
2302
  */
2142
2303
  fetchEIP712Domain: async (publicClient) => {
2143
- const TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
2144
- const ACL_IFACE = "function acl() view returns (address)";
2145
- const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
2146
- const aclAbi = viem.parseAbi([ACL_IFACE]);
2147
- const aclAddress = await publicClient.readContract({
2148
- address: TASK_MANAGER_ADDRESS,
2149
- abi: aclAbi,
2150
- functionName: "acl"
2151
- });
2152
- const domainAbi = viem.parseAbi([EIP712_DOMAIN_IFACE]);
2153
- const domain = await publicClient.readContract({
2154
- address: aclAddress,
2155
- abi: domainAbi,
2156
- functionName: "eip712Domain"
2157
- });
2158
- const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
2159
- return {
2160
- name,
2161
- version,
2162
- chainId: Number(chainId),
2163
- verifyingContract
2164
- };
2304
+ return getAclEIP712Domain(publicClient);
2165
2305
  },
2166
2306
  /**
2167
2307
  * Check if permit's signed domain matches the provided domain
@@ -2175,8 +2315,15 @@ var PermitUtils = {
2175
2315
  checkSignedDomainValid: async (permit, publicClient) => {
2176
2316
  if (permit._signedDomain == null)
2177
2317
  return false;
2178
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
2318
+ const domain = await getAclEIP712Domain(publicClient);
2179
2319
  return PermitUtils.matchesDomain(permit, domain);
2320
+ },
2321
+ /**
2322
+ * Check if permit passes the on-chain validation
2323
+ */
2324
+ checkValidityOnChain: async (permit, publicClient) => {
2325
+ const permission = PermitUtils.getPermission(permit);
2326
+ return checkPermitValidityOnChain(permission, publicClient);
2180
2327
  }
2181
2328
  };
2182
2329
  var PERMIT_STORE_DEFAULTS = {
@@ -2230,11 +2377,11 @@ var setPermit = (chainId, account, permit) => {
2230
2377
  state.permits[chainId] = {};
2231
2378
  if (state.permits[chainId][account] == null)
2232
2379
  state.permits[chainId][account] = {};
2233
- state.permits[chainId][account][PermitUtils.getHash(permit)] = PermitUtils.serialize(permit);
2380
+ state.permits[chainId][account][permit.hash] = PermitUtils.serialize(permit);
2234
2381
  })
2235
2382
  );
2236
2383
  };
2237
- var removePermit = (chainId, account, hash, force) => {
2384
+ var removePermit = (chainId, account, hash) => {
2238
2385
  clearStaleStore();
2239
2386
  _permitStore.setState(
2240
2387
  immer.produce((state) => {
@@ -2248,15 +2395,7 @@ var removePermit = (chainId, account, hash, force) => {
2248
2395
  if (accountPermits[hash] == null)
2249
2396
  return;
2250
2397
  if (state.activePermitHash[chainId][account] === hash) {
2251
- const otherPermitHash = Object.keys(accountPermits).find((key) => key !== hash && accountPermits[key] != null);
2252
- if (otherPermitHash) {
2253
- state.activePermitHash[chainId][account] = otherPermitHash;
2254
- } else {
2255
- if (!force) {
2256
- throw new Error("Cannot remove the last permit without force flag");
2257
- }
2258
- state.activePermitHash[chainId][account] = void 0;
2259
- }
2398
+ state.activePermitHash[chainId][account] = void 0;
2260
2399
  }
2261
2400
  accountPermits[hash] = void 0;
2262
2401
  })
@@ -2307,7 +2446,7 @@ var storeActivePermit = async (permit, publicClient, walletClient) => {
2307
2446
  const chainId = await publicClient.getChainId();
2308
2447
  const account = walletClient.account.address;
2309
2448
  permitStore.setPermit(chainId, account, permit);
2310
- permitStore.setActivePermitHash(chainId, account, PermitUtils.getHash(permit));
2449
+ permitStore.setActivePermitHash(chainId, account, permit.hash);
2311
2450
  };
2312
2451
  var createPermitWithSign = async (options, publicClient, walletClient, permitMethod) => {
2313
2452
  const permit = await permitMethod(options, publicClient, walletClient);
@@ -2365,7 +2504,7 @@ var getOrCreateSharingPermit = async (publicClient, walletClient, options, chain
2365
2504
  }
2366
2505
  return createSharing(options, publicClient, walletClient);
2367
2506
  };
2368
- var removePermit2 = async (chainId, account, hash, force) => permitStore.removePermit(chainId, account, hash, force);
2507
+ var removePermit2 = async (chainId, account, hash) => permitStore.removePermit(chainId, account, hash);
2369
2508
  var removeActivePermit = async (chainId, account) => permitStore.removeActivePermitHash(chainId, account);
2370
2509
  var permits = {
2371
2510
  getSnapshot: permitStore.store.getState,
@@ -2405,8 +2544,8 @@ var convertViaUtype = (utype, value) => {
2405
2544
  }
2406
2545
  };
2407
2546
 
2408
- // core/decrypt/MockQueryDecrypterAbi.ts
2409
- var MockQueryDecrypterAbi = [
2547
+ // core/decrypt/MockThresholdNetworkAbi.ts
2548
+ var MockThresholdNetworkAbi = [
2410
2549
  {
2411
2550
  type: "function",
2412
2551
  name: "acl",
@@ -2453,11 +2592,7 @@ var MockQueryDecrypterAbi = [
2453
2592
  { name: "expiration", type: "uint64", internalType: "uint64" },
2454
2593
  { name: "recipient", type: "address", internalType: "address" },
2455
2594
  { name: "validatorId", type: "uint256", internalType: "uint256" },
2456
- {
2457
- name: "validatorContract",
2458
- type: "address",
2459
- internalType: "address"
2460
- },
2595
+ { name: "validatorContract", type: "address", internalType: "address" },
2461
2596
  { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2462
2597
  { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2463
2598
  { name: "recipientSignature", type: "bytes", internalType: "bytes" }
@@ -2486,11 +2621,7 @@ var MockQueryDecrypterAbi = [
2486
2621
  { name: "expiration", type: "uint64", internalType: "uint64" },
2487
2622
  { name: "recipient", type: "address", internalType: "address" },
2488
2623
  { name: "validatorId", type: "uint256", internalType: "uint256" },
2489
- {
2490
- name: "validatorContract",
2491
- type: "address",
2492
- internalType: "address"
2493
- },
2624
+ { name: "validatorContract", type: "address", internalType: "address" },
2494
2625
  { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2495
2626
  { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2496
2627
  { name: "recipientSignature", type: "bytes", internalType: "bytes" }
@@ -2514,13 +2645,6 @@ var MockQueryDecrypterAbi = [
2514
2645
  outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
2515
2646
  stateMutability: "pure"
2516
2647
  },
2517
- {
2518
- type: "function",
2519
- name: "taskManager",
2520
- inputs: [],
2521
- outputs: [{ name: "", type: "address", internalType: "contract TaskManager" }],
2522
- stateMutability: "view"
2523
- },
2524
2648
  {
2525
2649
  type: "function",
2526
2650
  name: "unseal",
@@ -2531,16 +2655,80 @@ var MockQueryDecrypterAbi = [
2531
2655
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
2532
2656
  stateMutability: "pure"
2533
2657
  },
2534
- { type: "error", name: "NotAllowed", inputs: [] },
2535
- { type: "error", name: "SealingKeyInvalid", inputs: [] },
2536
- { type: "error", name: "SealingKeyMissing", inputs: [] }
2658
+ {
2659
+ type: "function",
2660
+ name: "mockAcl",
2661
+ inputs: [],
2662
+ outputs: [{ name: "", type: "address", internalType: "contract MockACL" }],
2663
+ stateMutability: "view"
2664
+ },
2665
+ {
2666
+ type: "function",
2667
+ name: "mockTaskManager",
2668
+ inputs: [],
2669
+ outputs: [{ name: "", type: "address", internalType: "contract MockTaskManager" }],
2670
+ stateMutability: "view"
2671
+ },
2672
+ {
2673
+ type: "function",
2674
+ name: "mockQueryDecrypt",
2675
+ inputs: [
2676
+ { name: "ctHash", type: "uint256", internalType: "uint256" },
2677
+ { name: "", type: "uint256", internalType: "uint256" },
2678
+ { name: "issuer", type: "address", internalType: "address" }
2679
+ ],
2680
+ outputs: [
2681
+ { name: "allowed", type: "bool", internalType: "bool" },
2682
+ { name: "error", type: "string", internalType: "string" },
2683
+ { name: "", type: "uint256", internalType: "uint256" }
2684
+ ],
2685
+ stateMutability: "view"
2686
+ },
2687
+ {
2688
+ type: "function",
2689
+ name: "decryptForTxWithPermit",
2690
+ inputs: [
2691
+ { name: "ctHash", type: "uint256", internalType: "uint256" },
2692
+ {
2693
+ name: "permission",
2694
+ type: "tuple",
2695
+ internalType: "struct Permission",
2696
+ components: [
2697
+ { name: "issuer", type: "address", internalType: "address" },
2698
+ { name: "expiration", type: "uint64", internalType: "uint64" },
2699
+ { name: "recipient", type: "address", internalType: "address" },
2700
+ { name: "validatorId", type: "uint256", internalType: "uint256" },
2701
+ { name: "validatorContract", type: "address", internalType: "address" },
2702
+ { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2703
+ { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2704
+ { name: "recipientSignature", type: "bytes", internalType: "bytes" }
2705
+ ]
2706
+ }
2707
+ ],
2708
+ outputs: [
2709
+ { name: "allowed", type: "bool", internalType: "bool" },
2710
+ { name: "error", type: "string", internalType: "string" },
2711
+ { name: "decryptedValue", type: "uint256", internalType: "uint256" }
2712
+ ],
2713
+ stateMutability: "view"
2714
+ },
2715
+ {
2716
+ type: "function",
2717
+ name: "decryptForTxWithoutPermit",
2718
+ inputs: [{ name: "ctHash", type: "uint256", internalType: "uint256" }],
2719
+ outputs: [
2720
+ { name: "allowed", type: "bool", internalType: "bool" },
2721
+ { name: "error", type: "string", internalType: "string" },
2722
+ { name: "decryptedValue", type: "uint256", internalType: "uint256" }
2723
+ ],
2724
+ stateMutability: "view"
2725
+ }
2537
2726
  ];
2538
2727
 
2539
- // core/decrypt/cofheMocksSealOutput.ts
2540
- var MockQueryDecrypterAddress = "0x0000000000000000000000000000000000000200";
2541
- async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSealOutputDelay) {
2542
- if (mocksSealOutputDelay > 0)
2543
- await sleep(mocksSealOutputDelay);
2728
+ // core/decrypt/cofheMocksDecryptForView.ts
2729
+ async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient, mocksDecryptDelay) {
2730
+ if (mocksDecryptDelay > 0)
2731
+ await sleep(mocksDecryptDelay);
2544
2732
  const permission = PermitUtils.getPermission(permit, true);
2545
2733
  const permissionWithBigInts = {
2546
2734
  ...permission,
@@ -2548,19 +2736,19 @@ async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSe
2548
2736
  validatorId: BigInt(permission.validatorId)
2549
2737
  };
2550
2738
  const [allowed, error, result] = await publicClient.readContract({
2551
- address: MockQueryDecrypterAddress,
2552
- abi: MockQueryDecrypterAbi,
2739
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
2740
+ abi: MockThresholdNetworkAbi,
2553
2741
  functionName: "querySealOutput",
2554
2742
  args: [ctHash, BigInt(utype), permissionWithBigInts]
2555
2743
  });
2556
2744
  if (error != "") {
2557
- throw new CofhesdkError({
2745
+ throw new CofheError({
2558
2746
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2559
2747
  message: `mocks querySealOutput call failed: ${error}`
2560
2748
  });
2561
2749
  }
2562
2750
  if (allowed == false) {
2563
- throw new CofhesdkError({
2751
+ throw new CofheError({
2564
2752
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2565
2753
  message: `mocks querySealOutput call failed: ACL Access Denied (NotAllowed)`
2566
2754
  });
@@ -2579,7 +2767,7 @@ function numberArrayToUint8Array(arr) {
2579
2767
  }
2580
2768
  function convertSealedData(sealed) {
2581
2769
  if (!sealed) {
2582
- throw new CofhesdkError({
2770
+ throw new CofheError({
2583
2771
  code: "SEAL_OUTPUT_RETURNED_NULL" /* SealOutputReturnedNull */,
2584
2772
  message: "Sealed data is missing from completed response"
2585
2773
  });
@@ -2606,7 +2794,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2606
2794
  body: JSON.stringify(body)
2607
2795
  });
2608
2796
  } catch (e) {
2609
- throw new CofhesdkError({
2797
+ throw new CofheError({
2610
2798
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2611
2799
  message: `sealOutput request failed`,
2612
2800
  hint: "Ensure the threshold network URL is valid and reachable.",
@@ -2625,7 +2813,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2625
2813
  } catch {
2626
2814
  errorMessage = response.statusText || errorMessage;
2627
2815
  }
2628
- throw new CofhesdkError({
2816
+ throw new CofheError({
2629
2817
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2630
2818
  message: `sealOutput request failed: ${errorMessage}`,
2631
2819
  hint: "Check the threshold network URL and request parameters.",
@@ -2641,7 +2829,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2641
2829
  try {
2642
2830
  submitResponse = await response.json();
2643
2831
  } catch (e) {
2644
- throw new CofhesdkError({
2832
+ throw new CofheError({
2645
2833
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2646
2834
  message: `Failed to parse sealOutput submit response`,
2647
2835
  cause: e instanceof Error ? e : void 0,
@@ -2652,7 +2840,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2652
2840
  });
2653
2841
  }
2654
2842
  if (!submitResponse.request_id) {
2655
- throw new CofhesdkError({
2843
+ throw new CofheError({
2656
2844
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2657
2845
  message: `sealOutput submit response missing request_id`,
2658
2846
  context: {
@@ -2669,7 +2857,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2669
2857
  let completed = false;
2670
2858
  while (!completed) {
2671
2859
  if (Date.now() - startTime > POLL_TIMEOUT_MS) {
2672
- throw new CofhesdkError({
2860
+ throw new CofheError({
2673
2861
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2674
2862
  message: `sealOutput polling timed out after ${POLL_TIMEOUT_MS}ms`,
2675
2863
  hint: "The request may still be processing. Try again later.",
@@ -2689,7 +2877,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2689
2877
  }
2690
2878
  });
2691
2879
  } catch (e) {
2692
- throw new CofhesdkError({
2880
+ throw new CofheError({
2693
2881
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2694
2882
  message: `sealOutput status poll failed`,
2695
2883
  hint: "Ensure the threshold network URL is valid and reachable.",
@@ -2701,7 +2889,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2701
2889
  });
2702
2890
  }
2703
2891
  if (response.status === 404) {
2704
- throw new CofhesdkError({
2892
+ throw new CofheError({
2705
2893
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2706
2894
  message: `sealOutput request not found: ${requestId}`,
2707
2895
  hint: "The request may have expired or been invalid.",
@@ -2719,7 +2907,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2719
2907
  } catch {
2720
2908
  errorMessage = response.statusText || errorMessage;
2721
2909
  }
2722
- throw new CofhesdkError({
2910
+ throw new CofheError({
2723
2911
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2724
2912
  message: `sealOutput status poll failed: ${errorMessage}`,
2725
2913
  context: {
@@ -2734,7 +2922,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2734
2922
  try {
2735
2923
  statusResponse = await response.json();
2736
2924
  } catch (e) {
2737
- throw new CofhesdkError({
2925
+ throw new CofheError({
2738
2926
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2739
2927
  message: `Failed to parse sealOutput status response`,
2740
2928
  cause: e instanceof Error ? e : void 0,
@@ -2747,7 +2935,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2747
2935
  if (statusResponse.status === "COMPLETED") {
2748
2936
  if (statusResponse.is_succeed === false) {
2749
2937
  const errorMessage = statusResponse.error_message || "Unknown error";
2750
- throw new CofhesdkError({
2938
+ throw new CofheError({
2751
2939
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2752
2940
  message: `sealOutput request failed: ${errorMessage}`,
2753
2941
  context: {
@@ -2758,7 +2946,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2758
2946
  });
2759
2947
  }
2760
2948
  if (!statusResponse.sealed) {
2761
- throw new CofhesdkError({
2949
+ throw new CofheError({
2762
2950
  code: "SEAL_OUTPUT_RETURNED_NULL" /* SealOutputReturnedNull */,
2763
2951
  message: `sealOutput request completed but returned no sealed data`,
2764
2952
  context: {
@@ -2772,7 +2960,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2772
2960
  }
2773
2961
  await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
2774
2962
  }
2775
- throw new CofhesdkError({
2963
+ throw new CofheError({
2776
2964
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2777
2965
  message: "Polling loop exited unexpectedly",
2778
2966
  context: {
@@ -2785,9 +2973,99 @@ async function tnSealOutputV2(ctHash, chainId, permission, thresholdNetworkUrl)
2785
2973
  const requestId = await submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission);
2786
2974
  return await pollSealOutputStatus(thresholdNetworkUrl, requestId);
2787
2975
  }
2976
+ async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient, mocksDecryptForTxDelay) {
2977
+ if (mocksDecryptForTxDelay > 0)
2978
+ await sleep(mocksDecryptForTxDelay);
2979
+ if (permit !== null) {
2980
+ let permission = PermitUtils.getPermission(permit, true);
2981
+ const permissionWithBigInts = {
2982
+ ...permission,
2983
+ expiration: BigInt(permission.expiration),
2984
+ validatorId: BigInt(permission.validatorId)
2985
+ };
2986
+ const [allowed2, error2, result2] = await publicClient.readContract({
2987
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
2988
+ abi: MockThresholdNetworkAbi,
2989
+ functionName: "decryptForTxWithPermit",
2990
+ args: [ctHash, permissionWithBigInts]
2991
+ });
2992
+ if (error2 != "") {
2993
+ throw new CofheError({
2994
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
2995
+ message: `mocks decryptForTx call failed: ${error2}`
2996
+ });
2997
+ }
2998
+ if (allowed2 == false) {
2999
+ throw new CofheError({
3000
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3001
+ message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
3002
+ });
3003
+ }
3004
+ const chainId2 = await publicClient.getChainId();
3005
+ const ctHashBigInt2 = BigInt(ctHash);
3006
+ const resultBigInt2 = BigInt(result2);
3007
+ const encryptionType2 = Number((ctHashBigInt2 & 0x7fn << 8n) >> 8n);
3008
+ const ctHashBytes322 = viem.pad(viem.toHex(ctHashBigInt2), { size: 32 });
3009
+ const packed2 = viem.encodePacked(
3010
+ ["uint256", "uint32", "uint64", "bytes32"],
3011
+ [resultBigInt2, encryptionType2, BigInt(chainId2), ctHashBytes322]
3012
+ );
3013
+ const messageHash2 = viem.keccak256(packed2);
3014
+ const signatureHex2 = await accounts.sign({
3015
+ hash: messageHash2,
3016
+ privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
3017
+ to: "hex"
3018
+ });
3019
+ const signature2 = signatureHex2.slice(2);
3020
+ return {
3021
+ ctHash,
3022
+ decryptedValue: BigInt(result2),
3023
+ signature: signature2
3024
+ };
3025
+ }
3026
+ const [allowed, error, result] = await publicClient.readContract({
3027
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
3028
+ abi: MockThresholdNetworkAbi,
3029
+ functionName: "decryptForTxWithoutPermit",
3030
+ args: [ctHash]
3031
+ });
3032
+ if (error != "") {
3033
+ throw new CofheError({
3034
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3035
+ message: `mocks decryptForTx call failed: ${error}`
3036
+ });
3037
+ }
3038
+ if (allowed == false) {
3039
+ throw new CofheError({
3040
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3041
+ message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
3042
+ });
3043
+ }
3044
+ const chainId = await publicClient.getChainId();
3045
+ const ctHashBigInt = BigInt(ctHash);
3046
+ const resultBigInt = BigInt(result);
3047
+ const encryptionType = Number((ctHashBigInt & 0x7fn << 8n) >> 8n);
3048
+ const ctHashBytes32 = viem.pad(viem.toHex(ctHashBigInt), { size: 32 });
3049
+ const packed = viem.encodePacked(
3050
+ ["uint256", "uint32", "uint64", "bytes32"],
3051
+ [resultBigInt, encryptionType, BigInt(chainId), ctHashBytes32]
3052
+ );
3053
+ const messageHash = viem.keccak256(packed);
3054
+ const signatureHex = await accounts.sign({
3055
+ hash: messageHash,
3056
+ privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
3057
+ to: "hex"
3058
+ });
3059
+ const signature = signatureHex.slice(2);
3060
+ return {
3061
+ ctHash,
3062
+ decryptedValue: BigInt(result),
3063
+ signature
3064
+ };
3065
+ }
2788
3066
 
2789
- // core/decrypt/decryptHandleBuilder.ts
2790
- var DecryptHandlesBuilder = class extends BaseBuilder {
3067
+ // core/decrypt/decryptForViewBuilder.ts
3068
+ var DecryptForViewBuilder = class extends BaseBuilder {
2791
3069
  ctHash;
2792
3070
  utype;
2793
3071
  permitHash;
@@ -2813,12 +3091,12 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2813
3091
  *
2814
3092
  * Example:
2815
3093
  * ```typescript
2816
- * const unsealed = await decryptHandle(ctHash, utype)
3094
+ * const unsealed = await client.decryptForView(ctHash, utype)
2817
3095
  * .setChainId(11155111)
2818
- * .decrypt();
3096
+ * .execute();
2819
3097
  * ```
2820
3098
  *
2821
- * @returns The chainable DecryptHandlesBuilder instance.
3099
+ * @returns The chainable DecryptForViewBuilder instance.
2822
3100
  */
2823
3101
  setChainId(chainId) {
2824
3102
  this.chainId = chainId;
@@ -2834,12 +3112,12 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2834
3112
  *
2835
3113
  * Example:
2836
3114
  * ```typescript
2837
- * const unsealed = await decryptHandle(ctHash, utype)
3115
+ * const unsealed = await client.decryptForView(ctHash, utype)
2838
3116
  * .setAccount('0x1234567890123456789012345678901234567890')
2839
- * .decrypt();
3117
+ * .execute();
2840
3118
  * ```
2841
3119
  *
2842
- * @returns The chainable DecryptHandlesBuilder instance.
3120
+ * @returns The chainable DecryptForViewBuilder instance.
2843
3121
  */
2844
3122
  setAccount(account) {
2845
3123
  this.account = account;
@@ -2848,6 +3126,19 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2848
3126
  getAccount() {
2849
3127
  return this.account;
2850
3128
  }
3129
+ withPermit(permitOrPermitHash) {
3130
+ if (typeof permitOrPermitHash === "string") {
3131
+ this.permitHash = permitOrPermitHash;
3132
+ this.permit = void 0;
3133
+ } else if (permitOrPermitHash === void 0) {
3134
+ this.permitHash = void 0;
3135
+ this.permit = void 0;
3136
+ } else {
3137
+ this.permit = permitOrPermitHash;
3138
+ this.permitHash = void 0;
3139
+ }
3140
+ return this;
3141
+ }
2851
3142
  /**
2852
3143
  * @param permitHash - Permit hash to decrypt values from. Used to fetch the correct permit.
2853
3144
  *
@@ -2856,16 +3147,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2856
3147
  *
2857
3148
  * Example:
2858
3149
  * ```typescript
2859
- * const unsealed = await decryptHandle(ctHash, utype)
3150
+ * const unsealed = await client.decryptForView(ctHash, utype)
2860
3151
  * .setPermitHash('0x1234567890123456789012345678901234567890')
2861
- * .decrypt();
3152
+ * .execute();
2862
3153
  * ```
2863
3154
  *
2864
- * @returns The chainable DecryptHandlesBuilder instance.
3155
+ * @returns The chainable DecryptForViewBuilder instance.
2865
3156
  */
3157
+ /** @deprecated Use `withPermit(permitHash)` instead. */
2866
3158
  setPermitHash(permitHash) {
2867
- this.permitHash = permitHash;
2868
- return this;
3159
+ return this.withPermit(permitHash);
2869
3160
  }
2870
3161
  getPermitHash() {
2871
3162
  return this.permitHash;
@@ -2877,16 +3168,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2877
3168
  *
2878
3169
  * Example:
2879
3170
  * ```typescript
2880
- * const unsealed = await decryptHandle(ctHash, utype)
3171
+ * const unsealed = await client.decryptForView(ctHash, utype)
2881
3172
  * .setPermit(permit)
2882
- * .decrypt();
3173
+ * .execute();
2883
3174
  * ```
2884
3175
  *
2885
- * @returns The chainable DecryptHandlesBuilder instance.
3176
+ * @returns The chainable DecryptForViewBuilder instance.
2886
3177
  */
3178
+ /** @deprecated Use `withPermit(permit)` instead. */
2887
3179
  setPermit(permit) {
2888
- this.permit = permit;
2889
- return this;
3180
+ return this.withPermit(permit);
2890
3181
  }
2891
3182
  getPermit() {
2892
3183
  return this.permit;
@@ -2897,7 +3188,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2897
3188
  }
2898
3189
  validateUtypeOrThrow() {
2899
3190
  if (!isValidUtype(this.utype))
2900
- throw new CofhesdkError({
3191
+ throw new CofheError({
2901
3192
  code: "INVALID_UTYPE" /* InvalidUtype */,
2902
3193
  message: `Invalid utype to decrypt to`,
2903
3194
  context: {
@@ -2913,7 +3204,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2913
3204
  if (this.permitHash) {
2914
3205
  const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
2915
3206
  if (!permit2) {
2916
- throw new CofhesdkError({
3207
+ throw new CofheError({
2917
3208
  code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
2918
3209
  message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
2919
3210
  hint: "Ensure the permit exists and is valid.",
@@ -2928,7 +3219,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2928
3219
  }
2929
3220
  const permit = await permits.getActivePermit(this.chainId, this.account);
2930
3221
  if (!permit) {
2931
- throw new CofhesdkError({
3222
+ throw new CofheError({
2932
3223
  code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
2933
3224
  message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
2934
3225
  hint: "Ensure a permit exists for this account on this chain.",
@@ -2945,8 +3236,8 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2945
3236
  */
2946
3237
  async mocksSealOutput(permit) {
2947
3238
  this.assertPublicClient();
2948
- const mocksSealOutputDelay = this.config.mocks.sealOutputDelay;
2949
- return cofheMocksSealOutput(this.ctHash, this.utype, permit, this.publicClient, mocksSealOutputDelay);
3239
+ const mocksDecryptDelay = this.config.mocks.decryptDelay;
3240
+ return cofheMocksDecryptForView(this.ctHash, this.utype, permit, this.publicClient, mocksDecryptDelay);
2950
3241
  }
2951
3242
  /**
2952
3243
  * In the production context, perform a true decryption with the CoFHE coprocessor.
@@ -2971,15 +3262,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2971
3262
  *
2972
3263
  * Example:
2973
3264
  * ```typescript
2974
- * const unsealed = await decryptHandle(ctHash, utype)
3265
+ * const unsealed = await client.decryptForView(ctHash, utype)
2975
3266
  * .setChainId(11155111) // optional
2976
3267
  * .setAccount('0x123...890') // optional
2977
- * .decrypt(); // execute
3268
+ * .withPermit() // optional
3269
+ * .execute(); // execute
2978
3270
  * ```
2979
3271
  *
2980
3272
  * @returns The unsealed item.
2981
3273
  */
2982
- async decrypt() {
3274
+ async execute() {
2983
3275
  this.validateUtypeOrThrow();
2984
3276
  const permit = await this.getResolvedPermit();
2985
3277
  PermitUtils.validate(permit);
@@ -2995,6 +3287,394 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2995
3287
  }
2996
3288
  };
2997
3289
 
3290
+ // core/decrypt/tnDecrypt.ts
3291
+ function normalizeSignature(signature) {
3292
+ if (typeof signature !== "string") {
3293
+ throw new CofheError({
3294
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3295
+ message: "decrypt response missing signature",
3296
+ context: {
3297
+ signature
3298
+ }
3299
+ });
3300
+ }
3301
+ const trimmed = signature.trim();
3302
+ if (trimmed.length === 0) {
3303
+ throw new CofheError({
3304
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3305
+ message: "decrypt response returned empty signature"
3306
+ });
3307
+ }
3308
+ return trimmed.startsWith("0x") ? trimmed.slice(2) : trimmed;
3309
+ }
3310
+ function parseDecryptedBytesToBigInt(decrypted) {
3311
+ if (!Array.isArray(decrypted)) {
3312
+ throw new CofheError({
3313
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3314
+ message: "decrypt response field <decrypted> must be a byte array",
3315
+ context: {
3316
+ decrypted
3317
+ }
3318
+ });
3319
+ }
3320
+ if (decrypted.length === 0) {
3321
+ throw new CofheError({
3322
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3323
+ message: "decrypt response field <decrypted> was an empty byte array",
3324
+ context: {
3325
+ decrypted
3326
+ }
3327
+ });
3328
+ }
3329
+ let hex = "";
3330
+ for (const b of decrypted) {
3331
+ if (typeof b !== "number" || !Number.isInteger(b) || b < 0 || b > 255) {
3332
+ throw new CofheError({
3333
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3334
+ message: "decrypt response field <decrypted> contained a non-byte value",
3335
+ context: {
3336
+ badElement: b,
3337
+ decrypted
3338
+ }
3339
+ });
3340
+ }
3341
+ hex += b.toString(16).padStart(2, "0");
3342
+ }
3343
+ return BigInt(`0x${hex}`);
3344
+ }
3345
+ function assertTnDecryptResponse(value) {
3346
+ if (value == null || typeof value !== "object") {
3347
+ throw new CofheError({
3348
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3349
+ message: "decrypt response must be a JSON object",
3350
+ context: {
3351
+ value
3352
+ }
3353
+ });
3354
+ }
3355
+ const v = value;
3356
+ const decrypted = v.decrypted;
3357
+ const signature = v.signature;
3358
+ const encryptionType = v.encryption_type;
3359
+ const errorMessage = v.error_message;
3360
+ if (!Array.isArray(decrypted)) {
3361
+ throw new CofheError({
3362
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3363
+ message: "decrypt response missing <decrypted> byte array",
3364
+ context: { decryptResponse: value }
3365
+ });
3366
+ }
3367
+ if (typeof signature !== "string") {
3368
+ throw new CofheError({
3369
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3370
+ message: "decrypt response missing <signature> string",
3371
+ context: { decryptResponse: value }
3372
+ });
3373
+ }
3374
+ if (typeof encryptionType !== "number") {
3375
+ throw new CofheError({
3376
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3377
+ message: "decrypt response missing <encryption_type> number",
3378
+ context: { decryptResponse: value }
3379
+ });
3380
+ }
3381
+ if (!(typeof errorMessage === "string" || errorMessage === null)) {
3382
+ throw new CofheError({
3383
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3384
+ message: "decrypt response field <error_message> must be string or null",
3385
+ context: { decryptResponse: value }
3386
+ });
3387
+ }
3388
+ return {
3389
+ decrypted,
3390
+ signature,
3391
+ encryption_type: encryptionType,
3392
+ error_message: errorMessage
3393
+ };
3394
+ }
3395
+ async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
3396
+ const body = {
3397
+ ct_tempkey: ctHash.toString(16).padStart(64, "0"),
3398
+ host_chain_id: chainId
3399
+ };
3400
+ if (permission) {
3401
+ body.permit = permission;
3402
+ }
3403
+ let response;
3404
+ try {
3405
+ response = await fetch(`${thresholdNetworkUrl}/decrypt`, {
3406
+ method: "POST",
3407
+ headers: {
3408
+ "Content-Type": "application/json"
3409
+ },
3410
+ body: JSON.stringify(body)
3411
+ });
3412
+ } catch (e) {
3413
+ throw new CofheError({
3414
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3415
+ message: `decrypt request failed`,
3416
+ hint: "Ensure the threshold network URL is valid and reachable.",
3417
+ cause: e instanceof Error ? e : void 0,
3418
+ context: {
3419
+ thresholdNetworkUrl,
3420
+ body
3421
+ }
3422
+ });
3423
+ }
3424
+ const responseText = await response.text();
3425
+ if (!response.ok) {
3426
+ let errorMessage = response.statusText || `HTTP ${response.status}`;
3427
+ try {
3428
+ const errorBody = JSON.parse(responseText);
3429
+ const maybeMessage = errorBody.error_message || errorBody.message;
3430
+ if (typeof maybeMessage === "string" && maybeMessage.length > 0)
3431
+ errorMessage = maybeMessage;
3432
+ } catch {
3433
+ const trimmed = responseText.trim();
3434
+ if (trimmed.length > 0)
3435
+ errorMessage = trimmed;
3436
+ }
3437
+ throw new CofheError({
3438
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3439
+ message: `decrypt request failed: ${errorMessage}`,
3440
+ hint: "Check the threshold network URL and request parameters.",
3441
+ context: {
3442
+ thresholdNetworkUrl,
3443
+ status: response.status,
3444
+ statusText: response.statusText,
3445
+ body,
3446
+ responseText
3447
+ }
3448
+ });
3449
+ }
3450
+ let rawJson;
3451
+ try {
3452
+ rawJson = JSON.parse(responseText);
3453
+ } catch (e) {
3454
+ throw new CofheError({
3455
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3456
+ message: `Failed to parse decrypt response`,
3457
+ cause: e instanceof Error ? e : void 0,
3458
+ context: {
3459
+ thresholdNetworkUrl,
3460
+ body,
3461
+ responseText
3462
+ }
3463
+ });
3464
+ }
3465
+ const decryptResponse = assertTnDecryptResponse(rawJson);
3466
+ if (decryptResponse.error_message) {
3467
+ throw new CofheError({
3468
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3469
+ message: `decrypt request failed: ${decryptResponse.error_message}`,
3470
+ context: {
3471
+ thresholdNetworkUrl,
3472
+ body,
3473
+ decryptResponse
3474
+ }
3475
+ });
3476
+ }
3477
+ const decryptedValue = parseDecryptedBytesToBigInt(decryptResponse.decrypted);
3478
+ const signature = normalizeSignature(decryptResponse.signature);
3479
+ return { decryptedValue, signature };
3480
+ }
3481
+
3482
+ // core/decrypt/decryptForTxBuilder.ts
3483
+ var DecryptForTxBuilder = class extends BaseBuilder {
3484
+ ctHash;
3485
+ permitHash;
3486
+ permit;
3487
+ permitSelection = "unset";
3488
+ constructor(params) {
3489
+ super({
3490
+ config: params.config,
3491
+ publicClient: params.publicClient,
3492
+ walletClient: params.walletClient,
3493
+ chainId: params.chainId,
3494
+ account: params.account,
3495
+ requireConnected: params.requireConnected
3496
+ });
3497
+ this.ctHash = params.ctHash;
3498
+ }
3499
+ setChainId(chainId) {
3500
+ this.chainId = chainId;
3501
+ return this;
3502
+ }
3503
+ getChainId() {
3504
+ return this.chainId;
3505
+ }
3506
+ setAccount(account) {
3507
+ this.account = account;
3508
+ return this;
3509
+ }
3510
+ getAccount() {
3511
+ return this.account;
3512
+ }
3513
+ withPermit(permitOrPermitHash) {
3514
+ if (this.permitSelection === "with-permit") {
3515
+ throw new CofheError({
3516
+ code: "INTERNAL_ERROR" /* InternalError */,
3517
+ message: "decryptForTx: withPermit() can only be selected once.",
3518
+ hint: "Choose the permit mode once. If you need a different permit, start a new decryptForTx() builder chain."
3519
+ });
3520
+ }
3521
+ if (this.permitSelection === "without-permit") {
3522
+ throw new CofheError({
3523
+ code: "INTERNAL_ERROR" /* InternalError */,
3524
+ message: "decryptForTx: cannot call withPermit() after withoutPermit() has been selected.",
3525
+ hint: "Choose exactly one permit mode: either call .withPermit(...) or .withoutPermit(), but not both."
3526
+ });
3527
+ }
3528
+ this.permitSelection = "with-permit";
3529
+ if (typeof permitOrPermitHash === "string") {
3530
+ this.permitHash = permitOrPermitHash;
3531
+ this.permit = void 0;
3532
+ } else if (permitOrPermitHash === void 0) {
3533
+ this.permitHash = void 0;
3534
+ this.permit = void 0;
3535
+ } else {
3536
+ this.permit = permitOrPermitHash;
3537
+ this.permitHash = void 0;
3538
+ }
3539
+ return this;
3540
+ }
3541
+ /**
3542
+ * Select "no permit" mode.
3543
+ *
3544
+ * This uses global allowance (no permit required) and sends an empty permission payload to `/decrypt`.
3545
+ */
3546
+ withoutPermit() {
3547
+ if (this.permitSelection === "without-permit") {
3548
+ throw new CofheError({
3549
+ code: "INTERNAL_ERROR" /* InternalError */,
3550
+ message: "decryptForTx: withoutPermit() can only be selected once.",
3551
+ hint: "Choose the permit mode once. If you need a different mode, start a new decryptForTx() builder chain."
3552
+ });
3553
+ }
3554
+ if (this.permitSelection === "with-permit") {
3555
+ throw new CofheError({
3556
+ code: "INTERNAL_ERROR" /* InternalError */,
3557
+ message: "decryptForTx: cannot call withoutPermit() after withPermit() has been selected.",
3558
+ hint: "Choose exactly one permit mode: either call .withPermit(...) or .withoutPermit(), but not both."
3559
+ });
3560
+ }
3561
+ this.permitSelection = "without-permit";
3562
+ this.permitHash = void 0;
3563
+ this.permit = void 0;
3564
+ return this;
3565
+ }
3566
+ getPermit() {
3567
+ return this.permit;
3568
+ }
3569
+ getPermitHash() {
3570
+ return this.permitHash;
3571
+ }
3572
+ async getThresholdNetworkUrl() {
3573
+ this.assertChainId();
3574
+ return getThresholdNetworkUrlOrThrow(this.config, this.chainId);
3575
+ }
3576
+ async getResolvedPermit() {
3577
+ if (this.permitSelection === "unset") {
3578
+ throw new CofheError({
3579
+ code: "INTERNAL_ERROR" /* InternalError */,
3580
+ message: "decryptForTx: missing permit selection; call withPermit(...) or withoutPermit() before execute().",
3581
+ hint: "Call .withPermit() to use the active permit, or .withoutPermit() for global allowance."
3582
+ });
3583
+ }
3584
+ if (this.permitSelection === "without-permit") {
3585
+ return null;
3586
+ }
3587
+ if (this.permit)
3588
+ return this.permit;
3589
+ this.assertChainId();
3590
+ this.assertAccount();
3591
+ if (this.permitHash) {
3592
+ const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
3593
+ if (!permit2) {
3594
+ throw new CofheError({
3595
+ code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
3596
+ message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
3597
+ hint: "Ensure the permit exists and is valid.",
3598
+ context: {
3599
+ chainId: this.chainId,
3600
+ account: this.account,
3601
+ permitHash: this.permitHash
3602
+ }
3603
+ });
3604
+ }
3605
+ return permit2;
3606
+ }
3607
+ const permit = await permits.getActivePermit(this.chainId, this.account);
3608
+ if (!permit) {
3609
+ throw new CofheError({
3610
+ code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
3611
+ message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
3612
+ hint: "Create a permit (e.g. client.permits.createSelf(...)) and/or set it active (client.permits.selectActivePermit(hash)).",
3613
+ context: {
3614
+ chainId: this.chainId,
3615
+ account: this.account
3616
+ }
3617
+ });
3618
+ }
3619
+ return permit;
3620
+ }
3621
+ /**
3622
+ * On hardhat, interact with MockThresholdNetwork contract
3623
+ */
3624
+ async mocksDecryptForTx(permit) {
3625
+ this.assertPublicClient();
3626
+ const delay = this.config.mocks.decryptDelay;
3627
+ const result = await cofheMocksDecryptForTx(this.ctHash, 0, permit, this.publicClient, delay);
3628
+ return result;
3629
+ }
3630
+ /**
3631
+ * In the production context, perform a true decryption with the CoFHE coprocessor.
3632
+ */
3633
+ async productionDecryptForTx(permit) {
3634
+ this.assertChainId();
3635
+ this.assertPublicClient();
3636
+ const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
3637
+ const permission = permit ? PermitUtils.getPermission(permit, true) : null;
3638
+ const { decryptedValue, signature } = await tnDecrypt(this.ctHash, this.chainId, permission, thresholdNetworkUrl);
3639
+ return {
3640
+ ctHash: this.ctHash,
3641
+ decryptedValue,
3642
+ signature
3643
+ };
3644
+ }
3645
+ /**
3646
+ * Final step of the decryptForTx process. MUST BE CALLED LAST IN THE CHAIN.
3647
+ *
3648
+ * You must explicitly choose one permit mode before calling `execute()`:
3649
+ * - `withPermit(permit)` / `withPermit(permitHash)` / `withPermit()` (active permit)
3650
+ * - `withoutPermit()` (global allowance)
3651
+ */
3652
+ async execute() {
3653
+ const permit = await this.getResolvedPermit();
3654
+ if (permit !== null) {
3655
+ PermitUtils.validate(permit);
3656
+ PermitUtils.isValid(permit);
3657
+ const chainId = permit._signedDomain.chainId;
3658
+ if (chainId === hardhat2.id) {
3659
+ return await this.mocksDecryptForTx(permit);
3660
+ } else {
3661
+ return await this.productionDecryptForTx(permit);
3662
+ }
3663
+ } else {
3664
+ if (!this.chainId) {
3665
+ this.assertPublicClient();
3666
+ this.chainId = await getPublicClientChainID(this.publicClient);
3667
+ }
3668
+ this.assertChainId();
3669
+ if (this.chainId === hardhat2.id) {
3670
+ return await this.mocksDecryptForTx(null);
3671
+ } else {
3672
+ return await this.productionDecryptForTx(null);
3673
+ }
3674
+ }
3675
+ }
3676
+ };
3677
+
2998
3678
  // core/client.ts
2999
3679
  var InitialConnectStore = {
3000
3680
  connected: false,
@@ -3005,9 +3685,10 @@ var InitialConnectStore = {
3005
3685
  publicClient: void 0,
3006
3686
  walletClient: void 0
3007
3687
  };
3008
- function createCofhesdkClientBase(opts) {
3688
+ function createCofheClientBase(opts) {
3009
3689
  const keysStorage = createKeysStore(opts.config.fheKeyStorage);
3010
3690
  const connectStore = vanilla.createStore(() => InitialConnectStore);
3691
+ let connectAttemptId = 0;
3011
3692
  const updateConnectState = (partial) => {
3012
3693
  connectStore.setState((state) => ({ ...state, ...partial }));
3013
3694
  };
@@ -3015,7 +3696,7 @@ function createCofhesdkClientBase(opts) {
3015
3696
  const state = connectStore.getState();
3016
3697
  const notConnected = !state.connected || !state.account || !state.chainId || !state.publicClient || !state.walletClient;
3017
3698
  if (notConnected) {
3018
- throw new CofhesdkError({
3699
+ throw new CofheError({
3019
3700
  code: "NOT_CONNECTED" /* NotConnected */,
3020
3701
  message: "Client must be connected, account and chainId must be initialized",
3021
3702
  hint: "Ensure client.connect() has been called and awaited.",
@@ -3033,6 +3714,8 @@ function createCofhesdkClientBase(opts) {
3033
3714
  const state = connectStore.getState();
3034
3715
  if (state.connected && state.publicClient === publicClient && state.walletClient === walletClient)
3035
3716
  return;
3717
+ connectAttemptId += 1;
3718
+ const localAttemptId = connectAttemptId;
3036
3719
  updateConnectState({
3037
3720
  ...InitialConnectStore,
3038
3721
  connecting: true
@@ -3040,6 +3723,8 @@ function createCofhesdkClientBase(opts) {
3040
3723
  try {
3041
3724
  const chainId = await getPublicClientChainID(publicClient);
3042
3725
  const account = await getWalletClientAccount(walletClient);
3726
+ if (localAttemptId !== connectAttemptId)
3727
+ return;
3043
3728
  updateConnectState({
3044
3729
  connected: true,
3045
3730
  connecting: false,
@@ -3050,6 +3735,8 @@ function createCofhesdkClientBase(opts) {
3050
3735
  walletClient
3051
3736
  });
3052
3737
  } catch (e) {
3738
+ if (localAttemptId !== connectAttemptId)
3739
+ return;
3053
3740
  updateConnectState({
3054
3741
  ...InitialConnectStore,
3055
3742
  connectError: e
@@ -3057,6 +3744,10 @@ function createCofhesdkClientBase(opts) {
3057
3744
  throw e;
3058
3745
  }
3059
3746
  }
3747
+ function disconnect() {
3748
+ connectAttemptId += 1;
3749
+ updateConnectState({ ...InitialConnectStore });
3750
+ }
3060
3751
  function encryptInputs(inputs) {
3061
3752
  const state = connectStore.getState();
3062
3753
  return new EncryptInputsBuilder({
@@ -3076,16 +3767,28 @@ function createCofhesdkClientBase(opts) {
3076
3767
  requireConnected: _requireConnected
3077
3768
  });
3078
3769
  }
3079
- function decryptHandle(ctHash, utype) {
3770
+ function decryptForView(ctHash, utype) {
3080
3771
  const state = connectStore.getState();
3081
- return new DecryptHandlesBuilder({
3772
+ return new DecryptForViewBuilder({
3082
3773
  ctHash,
3083
3774
  utype,
3084
- chainId: state.chainId ?? void 0,
3085
- account: state.account ?? void 0,
3775
+ chainId: state.chainId,
3776
+ account: state.account,
3086
3777
  config: opts.config,
3087
- publicClient: state.publicClient ?? void 0,
3088
- walletClient: state.walletClient ?? void 0,
3778
+ publicClient: state.publicClient,
3779
+ walletClient: state.walletClient,
3780
+ requireConnected: _requireConnected
3781
+ });
3782
+ }
3783
+ function decryptForTx(ctHash) {
3784
+ const state = connectStore.getState();
3785
+ return new DecryptForTxBuilder({
3786
+ ctHash,
3787
+ chainId: state.chainId,
3788
+ account: state.account,
3789
+ config: opts.config,
3790
+ publicClient: state.publicClient,
3791
+ walletClient: state.walletClient,
3089
3792
  requireConnected: _requireConnected
3090
3793
  });
3091
3794
  }
@@ -3094,7 +3797,7 @@ function createCofhesdkClientBase(opts) {
3094
3797
  const _chainId = chainId ?? state.chainId;
3095
3798
  const _account = account ?? state.account;
3096
3799
  if (_chainId == null || _account == null) {
3097
- throw new CofhesdkError({
3800
+ throw new CofheError({
3098
3801
  code: "NOT_CONNECTED" /* NotConnected */,
3099
3802
  message: "ChainId or account not available.",
3100
3803
  hint: "Ensure client.connect() has been called, or provide chainId and account explicitly.",
@@ -3161,9 +3864,9 @@ function createCofhesdkClientBase(opts) {
3161
3864
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
3162
3865
  return permits.selectActivePermit(_chainId, _account, hash);
3163
3866
  },
3164
- removePermit: async (hash, chainId, account, force) => {
3867
+ removePermit: async (hash, chainId, account) => {
3165
3868
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
3166
- return permits.removePermit(_chainId, _account, hash, force);
3869
+ return permits.removePermit(_chainId, _account, hash);
3167
3870
  },
3168
3871
  removeActivePermit: async (chainId, account) => {
3169
3872
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
@@ -3179,6 +3882,9 @@ function createCofhesdkClientBase(opts) {
3179
3882
  getSnapshot: connectStore.getState,
3180
3883
  subscribe: connectStore.subscribe,
3181
3884
  // flags (read-only: reflect snapshot)
3885
+ get connection() {
3886
+ return connectStore.getState();
3887
+ },
3182
3888
  get connected() {
3183
3889
  return connectStore.getState().connected;
3184
3890
  },
@@ -3188,8 +3894,14 @@ function createCofhesdkClientBase(opts) {
3188
3894
  // config & platform-specific (read-only)
3189
3895
  config: opts.config,
3190
3896
  connect,
3897
+ disconnect,
3191
3898
  encryptInputs,
3192
- decryptHandle,
3899
+ decryptForView,
3900
+ /**
3901
+ * @deprecated Use `decryptForView` instead. Kept for backward compatibility.
3902
+ */
3903
+ decryptHandle: decryptForView,
3904
+ decryptForTx,
3193
3905
  permits: clientPermits
3194
3906
  // Add SDK-specific methods below that require connection
3195
3907
  // Example:
@@ -3265,15 +3977,15 @@ var zkBuilderAndCrsGenerator = (fhe, crs) => {
3265
3977
  const zkCrs = nodeTfhe.CompactPkeCrs.deserialize(fromHexString2(crs));
3266
3978
  return { zkBuilder, zkCrs };
3267
3979
  };
3268
- function createCofhesdkConfig(config) {
3269
- return createCofhesdkConfigBase({
3980
+ function createCofheConfig(config) {
3981
+ return createCofheConfigBase({
3270
3982
  environment: "node",
3271
3983
  ...config,
3272
3984
  fheKeyStorage: config.fheKeyStorage === null ? null : config.fheKeyStorage ?? createNodeStorage()
3273
3985
  });
3274
3986
  }
3275
- function createCofhesdkClient(config) {
3276
- return createCofhesdkClientBase({
3987
+ function createCofheClient(config) {
3988
+ return createCofheClientBase({
3277
3989
  config,
3278
3990
  zkBuilderAndCrsGenerator,
3279
3991
  tfhePublicKeyDeserializer,
@@ -3282,5 +3994,5 @@ function createCofhesdkClient(config) {
3282
3994
  });
3283
3995
  }
3284
3996
 
3285
- exports.createCofhesdkClient = createCofhesdkClient;
3286
- exports.createCofhesdkConfig = createCofhesdkConfig;
3997
+ exports.createCofheClient = createCofheClient;
3998
+ exports.createCofheConfig = createCofheConfig;