@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/web.cjs CHANGED
@@ -38,7 +38,7 @@ var init__default = /*#__PURE__*/_interopDefault(init);
38
38
  // core/client.ts
39
39
 
40
40
  // core/error.ts
41
- var CofhesdkError = class _CofhesdkError extends Error {
41
+ var CofheError = class _CofheError extends Error {
42
42
  code;
43
43
  cause;
44
44
  hint;
@@ -46,25 +46,25 @@ var CofhesdkError = class _CofhesdkError extends Error {
46
46
  constructor({ code, message, cause, hint, context }) {
47
47
  const fullMessage = cause ? `${message} | Caused by: ${cause.message}` : message;
48
48
  super(fullMessage);
49
- this.name = "CofhesdkError";
49
+ this.name = "CofheError";
50
50
  this.code = code;
51
51
  this.cause = cause;
52
52
  this.hint = hint;
53
53
  this.context = context;
54
54
  if (Error.captureStackTrace) {
55
- Error.captureStackTrace(this, _CofhesdkError);
55
+ Error.captureStackTrace(this, _CofheError);
56
56
  }
57
57
  }
58
58
  /**
59
- * Creates a CofhesdkError from an unknown error
60
- * If the error is a CofhesdkError, it is returned unchanged, else a new CofhesdkError is created
61
- * If a wrapperError is provided, it is used to create the new CofhesdkError, else a default is used
59
+ * Creates a CofheError from an unknown error
60
+ * If the error is a CofheError, it is returned unchanged, else a new CofheError is created
61
+ * If a wrapperError is provided, it is used to create the new CofheError, else a default is used
62
62
  */
63
63
  static fromError(error, wrapperError) {
64
- if (isCofhesdkError(error))
64
+ if (isCofheError(error))
65
65
  return error;
66
66
  const cause = error instanceof Error ? error : new Error(`${error}`);
67
- return new _CofhesdkError({
67
+ return new _CofheError({
68
68
  code: wrapperError?.code ?? "INTERNAL_ERROR" /* InternalError */,
69
69
  message: wrapperError?.message ?? "An internal error occurred",
70
70
  hint: wrapperError?.hint,
@@ -124,7 +124,7 @@ var bigintSafeJsonStringify = (value) => {
124
124
  return value2;
125
125
  });
126
126
  };
127
- var isCofhesdkError = (error) => error instanceof CofhesdkError;
127
+ var isCofheError = (error) => error instanceof CofheError;
128
128
 
129
129
  // core/types.ts
130
130
  var FheUintUTypes = [
@@ -168,14 +168,14 @@ async function getPublicClientChainID(publicClient) {
168
168
  try {
169
169
  chainId = publicClient.chain?.id ?? await publicClient.getChainId();
170
170
  } catch (e) {
171
- throw new CofhesdkError({
171
+ throw new CofheError({
172
172
  code: "PUBLIC_WALLET_GET_CHAIN_ID_FAILED" /* PublicWalletGetChainIdFailed */,
173
173
  message: "getting chain ID from public client failed",
174
174
  cause: e instanceof Error ? e : void 0
175
175
  });
176
176
  }
177
177
  if (chainId === null) {
178
- throw new CofhesdkError({
178
+ throw new CofheError({
179
179
  code: "PUBLIC_WALLET_GET_CHAIN_ID_FAILED" /* PublicWalletGetChainIdFailed */,
180
180
  message: "chain ID from public client is null"
181
181
  });
@@ -190,14 +190,14 @@ async function getWalletClientAccount(walletClient) {
190
190
  address = (await walletClient.getAddresses())?.[0];
191
191
  }
192
192
  } catch (e) {
193
- throw new CofhesdkError({
193
+ throw new CofheError({
194
194
  code: "PUBLIC_WALLET_GET_ADDRESSES_FAILED" /* PublicWalletGetAddressesFailed */,
195
195
  message: "getting address from wallet client failed",
196
196
  cause: e instanceof Error ? e : void 0
197
197
  });
198
198
  }
199
199
  if (!address) {
200
- throw new CofhesdkError({
200
+ throw new CofheError({
201
201
  code: "PUBLIC_WALLET_GET_ADDRESSES_FAILED" /* PublicWalletGetAddressesFailed */,
202
202
  message: "address from wallet client is null"
203
203
  });
@@ -301,7 +301,7 @@ var zkPack = (items, builder) => {
301
301
  break;
302
302
  }
303
303
  default: {
304
- throw new CofhesdkError({
304
+ throw new CofheError({
305
305
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
306
306
  message: `Invalid utype: ${item.utype}`,
307
307
  hint: `Ensure that the utype is valid, using the Encryptable type, for example: Encryptable.uint128(100n)`,
@@ -313,7 +313,7 @@ var zkPack = (items, builder) => {
313
313
  }
314
314
  }
315
315
  if (totalBits > MAX_ENCRYPTABLE_BITS) {
316
- throw new CofhesdkError({
316
+ throw new CofheError({
317
317
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
318
318
  message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
319
319
  hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
@@ -377,14 +377,14 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
377
377
  });
378
378
  if (!response.ok) {
379
379
  const errorBody = await response.text();
380
- throw new CofhesdkError({
380
+ throw new CofheError({
381
381
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
382
382
  message: `HTTP error! ZK proof verification failed - ${errorBody}`
383
383
  });
384
384
  }
385
385
  const json = await response.json();
386
386
  if (json.status !== "success") {
387
- throw new CofhesdkError({
387
+ throw new CofheError({
388
388
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
389
389
  message: `ZK proof verification response malformed - ${json.error}`
390
390
  });
@@ -396,7 +396,7 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
396
396
  };
397
397
  });
398
398
  } catch (e) {
399
- throw new CofhesdkError({
399
+ throw new CofheError({
400
400
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
401
401
  message: `ZK proof verification failed`,
402
402
  cause: e instanceof Error ? e : void 0
@@ -514,8 +514,15 @@ var MockZkVerifierAbi = [
514
514
  },
515
515
  { type: "error", name: "InvalidInputs", inputs: [] }
516
516
  ];
517
- var MocksZkVerifierAddress = "0x0000000000000000000000000000000000000100";
517
+
518
+ // core/consts.ts
519
+ var TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
520
+ var MOCKS_ZK_VERIFIER_ADDRESS = "0x0000000000000000000000000000000000005001";
521
+ var MOCKS_THRESHOLD_NETWORK_ADDRESS = "0x0000000000000000000000000000000000005002";
518
522
  var MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = "0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512";
523
+ var MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d";
524
+
525
+ // core/encrypt/cofheMocksZkVerifySign.ts
519
526
  function createMockZkVerifierSigner() {
520
527
  return viem.createWalletClient({
521
528
  chain: chains.hardhat,
@@ -558,7 +565,7 @@ async function cofheMocksCheckEncryptableBits(items) {
558
565
  }
559
566
  }
560
567
  if (totalBits > MAX_ENCRYPTABLE_BITS) {
561
- throw new CofhesdkError({
568
+ throw new CofheError({
562
569
  code: "ZK_PACK_FAILED" /* ZkPackFailed */,
563
570
  message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
564
571
  hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
@@ -581,18 +588,18 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
581
588
  let ctHashes;
582
589
  try {
583
590
  ctHashes = await publicClient.readContract({
584
- address: MocksZkVerifierAddress,
591
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
585
592
  abi: MockZkVerifierAbi,
586
593
  functionName: "zkVerifyCalcCtHashesPacked",
587
594
  args: calcCtHashesArgs
588
595
  });
589
596
  } catch (err) {
590
- throw new CofhesdkError({
597
+ throw new CofheError({
591
598
  code: "ZK_MOCKS_CALC_CT_HASHES_FAILED" /* ZkMocksCalcCtHashesFailed */,
592
599
  message: `mockZkVerifySign calcCtHashes failed while calling zkVerifyCalcCtHashesPacked`,
593
600
  cause: err instanceof Error ? err : void 0,
594
601
  context: {
595
- address: MocksZkVerifierAddress,
602
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
596
603
  items,
597
604
  account,
598
605
  securityZone,
@@ -602,7 +609,7 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
602
609
  });
603
610
  }
604
611
  if (ctHashes.length !== items.length) {
605
- throw new CofhesdkError({
612
+ throw new CofheError({
606
613
  code: "ZK_MOCKS_CALC_CT_HASHES_FAILED" /* ZkMocksCalcCtHashesFailed */,
607
614
  message: `mockZkVerifySign calcCtHashes returned incorrect number of ctHashes`,
608
615
  context: {
@@ -625,7 +632,7 @@ async function insertCtHashes(items, walletClient) {
625
632
  try {
626
633
  const account = walletClient.account;
627
634
  await walletClient.writeContract({
628
- address: MocksZkVerifierAddress,
635
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
629
636
  abi: MockZkVerifierAbi,
630
637
  functionName: "insertPackedCtHashes",
631
638
  args: insertPackedCtHashesArgs,
@@ -633,7 +640,7 @@ async function insertCtHashes(items, walletClient) {
633
640
  account
634
641
  });
635
642
  } catch (err) {
636
- throw new CofhesdkError({
643
+ throw new CofheError({
637
644
  code: "ZK_MOCKS_INSERT_CT_HASHES_FAILED" /* ZkMocksInsertCtHashesFailed */,
638
645
  message: `mockZkVerifySign insertPackedCtHashes failed while calling insertPackedCtHashes`,
639
646
  cause: err instanceof Error ? err : void 0,
@@ -651,7 +658,7 @@ async function createProofSignatures(items, securityZone) {
651
658
  try {
652
659
  encInputSignerClient = createMockZkVerifierSigner();
653
660
  } catch (err) {
654
- throw new CofhesdkError({
661
+ throw new CofheError({
655
662
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
656
663
  message: `mockZkVerifySign createProofSignatures failed while creating wallet client`,
657
664
  cause: err instanceof Error ? err : void 0,
@@ -672,7 +679,7 @@ async function createProofSignatures(items, securityZone) {
672
679
  signatures.push(signature);
673
680
  }
674
681
  } catch (err) {
675
- throw new CofhesdkError({
682
+ throw new CofheError({
676
683
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
677
684
  message: `mockZkVerifySign createProofSignatures failed while calling signMessage`,
678
685
  cause: err instanceof Error ? err : void 0,
@@ -683,7 +690,7 @@ async function createProofSignatures(items, securityZone) {
683
690
  });
684
691
  }
685
692
  if (signatures.length !== items.length) {
686
- throw new CofhesdkError({
693
+ throw new CofheError({
687
694
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
688
695
  message: `mockZkVerifySign createProofSignatures returned incorrect number of signatures`,
689
696
  context: {
@@ -713,21 +720,18 @@ var CofheChainSchema = zod.z.object({
713
720
  /** Network identifier */
714
721
  network: zod.z.string().min(1),
715
722
  /** coFhe service URL */
716
- coFheUrl: zod.z.string().url(),
723
+ coFheUrl: zod.z.url(),
717
724
  /** Verifier service URL */
718
- verifierUrl: zod.z.string().url(),
725
+ verifierUrl: zod.z.url(),
719
726
  /** Threshold network service URL */
720
- thresholdNetworkUrl: zod.z.string().url(),
727
+ thresholdNetworkUrl: zod.z.url(),
721
728
  /** Environment type */
722
729
  environment: EnvironmentSchema
723
730
  });
724
-
725
- // chains/defineChain.ts
726
731
  function defineChain(chainConfig) {
727
732
  const result = CofheChainSchema.safeParse(chainConfig);
728
733
  if (!result.success) {
729
- const errorMessages = result.error.errors.map((err) => `${err.path.join(".")}: ${err.message}`);
730
- throw new Error(`Invalid chain configuration: ${errorMessages.join(", ")}`);
734
+ throw new Error(`Invalid chain configuration: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
731
735
  }
732
736
  return result.data;
733
737
  }
@@ -743,43 +747,48 @@ var hardhat2 = defineChain({
743
747
  thresholdNetworkUrl: "http://127.0.0.1:3000",
744
748
  environment: "MOCK"
745
749
  });
746
- var CofhesdkConfigSchema = zod.z.object({
750
+ var CofheConfigSchema = zod.z.object({
747
751
  /** Environment that the SDK is running in */
748
752
  environment: zod.z.enum(["node", "hardhat", "web", "react"]).optional().default("node"),
749
753
  /** List of supported chain configurations */
750
754
  supportedChains: zod.z.array(zod.z.custom()),
751
- /** How permits are generated */
752
- permitGeneration: zod.z.enum(["ON_CONNECT", "ON_DECRYPT_HANDLES", "MANUAL"]).optional().default("ON_CONNECT"),
753
755
  /** Default permit expiration in seconds, default is 30 days */
754
756
  defaultPermitExpiration: zod.z.number().optional().default(60 * 60 * 24 * 30),
755
757
  /** Storage method for fhe keys (defaults to indexedDB on web, filesystem on node) */
756
758
  fheKeyStorage: zod.z.object({
757
- getItem: zod.z.function().args(zod.z.string()).returns(zod.z.promise(zod.z.any())),
758
- setItem: zod.z.function().args(zod.z.string(), zod.z.any()).returns(zod.z.promise(zod.z.void())),
759
- removeItem: zod.z.function().args(zod.z.string()).returns(zod.z.promise(zod.z.void()))
759
+ getItem: zod.z.custom((val) => typeof val === "function", {
760
+ message: "getItem must be a function"
761
+ }),
762
+ setItem: zod.z.custom((val) => typeof val === "function", {
763
+ message: "setItem must be a function"
764
+ }),
765
+ removeItem: zod.z.custom((val) => typeof val === "function", {
766
+ message: "removeItem must be a function"
767
+ })
760
768
  }).or(zod.z.null()).default(null),
761
769
  /** Whether to use Web Workers for ZK proof generation (web platform only) */
762
770
  useWorkers: zod.z.boolean().optional().default(true),
763
771
  /** Mocks configs */
764
772
  mocks: zod.z.object({
765
- sealOutputDelay: zod.z.number().optional().default(0)
766
- }).optional().default({ sealOutputDelay: 0 }),
773
+ decryptDelay: zod.z.number().optional().default(0),
774
+ encryptDelay: zod.z.union([zod.z.number(), zod.z.tuple([zod.z.number(), zod.z.number(), zod.z.number(), zod.z.number(), zod.z.number()])]).optional().default([100, 100, 100, 500, 500])
775
+ }).optional().default({ decryptDelay: 0, encryptDelay: [100, 100, 100, 500, 500] }),
767
776
  /** Internal configuration */
768
777
  _internal: zod.z.object({
769
778
  zkvWalletClient: zod.z.any().optional()
770
779
  }).optional()
771
780
  });
772
- function createCofhesdkConfigBase(config) {
773
- const result = CofhesdkConfigSchema.safeParse(config);
781
+ function createCofheConfigBase(config) {
782
+ const result = CofheConfigSchema.safeParse(config);
774
783
  if (!result.success) {
775
- throw new Error(`Invalid cofhesdk configuration: ${result.error.message}`);
784
+ throw new Error(`Invalid cofhe configuration: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
776
785
  }
777
786
  return result.data;
778
787
  }
779
788
  function getSupportedChainOrThrow(config, chainId) {
780
789
  const supportedChain = config.supportedChains.find((chain) => chain.id === chainId);
781
790
  if (!supportedChain) {
782
- throw new CofhesdkError({
791
+ throw new CofheError({
783
792
  code: "UNSUPPORTED_CHAIN" /* UnsupportedChain */,
784
793
  message: `Config does not support chain <${chainId}>`,
785
794
  hint: "Ensure config passed to client has been created with this chain in the config.supportedChains array.",
@@ -795,7 +804,7 @@ function getCoFheUrlOrThrow(config, chainId) {
795
804
  const supportedChain = getSupportedChainOrThrow(config, chainId);
796
805
  const url = supportedChain.coFheUrl;
797
806
  if (!url) {
798
- throw new CofhesdkError({
807
+ throw new CofheError({
799
808
  code: "MISSING_CONFIG" /* MissingConfig */,
800
809
  message: `CoFHE URL is not configured for chain <${chainId}>`,
801
810
  hint: "Ensure this chain config includes a coFheUrl property.",
@@ -808,7 +817,7 @@ function getZkVerifierUrlOrThrow(config, chainId) {
808
817
  const supportedChain = getSupportedChainOrThrow(config, chainId);
809
818
  const url = supportedChain.verifierUrl;
810
819
  if (!url) {
811
- throw new CofhesdkError({
820
+ throw new CofheError({
812
821
  code: "ZK_VERIFIER_URL_UNINITIALIZED" /* ZkVerifierUrlUninitialized */,
813
822
  message: `ZK verifier URL is not configured for chain <${chainId}>`,
814
823
  hint: "Ensure this chain config includes a verifierUrl property.",
@@ -821,7 +830,7 @@ function getThresholdNetworkUrlOrThrow(config, chainId) {
821
830
  const supportedChain = getSupportedChainOrThrow(config, chainId);
822
831
  const url = supportedChain.thresholdNetworkUrl;
823
832
  if (!url) {
824
- throw new CofhesdkError({
833
+ throw new CofheError({
825
834
  code: "THRESHOLD_NETWORK_URL_UNINITIALIZED" /* ThresholdNetworkUrlUninitialized */,
826
835
  message: `Threshold network URL is not configured for chain <${chainId}>`,
827
836
  hint: "Ensure this chain config includes a thresholdNetworkUrl property.",
@@ -1033,7 +1042,7 @@ var BaseBuilder = class {
1033
1042
  account;
1034
1043
  constructor(params) {
1035
1044
  if (!params.config) {
1036
- throw new CofhesdkError({
1045
+ throw new CofheError({
1037
1046
  code: "MISSING_CONFIG" /* MissingConfig */,
1038
1047
  message: "Builder config is undefined",
1039
1048
  hint: "Ensure client has been created with a config.",
@@ -1051,12 +1060,12 @@ var BaseBuilder = class {
1051
1060
  }
1052
1061
  /**
1053
1062
  * Asserts that this.chainId is populated
1054
- * @throws {CofhesdkError} If chainId is not set
1063
+ * @throws {CofheError} If chainId is not set
1055
1064
  */
1056
1065
  assertChainId() {
1057
1066
  if (this.chainId)
1058
1067
  return;
1059
- throw new CofhesdkError({
1068
+ throw new CofheError({
1060
1069
  code: "CHAIN_ID_UNINITIALIZED" /* ChainIdUninitialized */,
1061
1070
  message: "Chain ID is not set",
1062
1071
  hint: "Ensure client.connect() has been called and awaited, or use setChainId(...) to set the chainId explicitly.",
@@ -1067,12 +1076,12 @@ var BaseBuilder = class {
1067
1076
  }
1068
1077
  /**
1069
1078
  * Asserts that this.account is populated
1070
- * @throws {CofhesdkError} If account is not set
1079
+ * @throws {CofheError} If account is not set
1071
1080
  */
1072
1081
  assertAccount() {
1073
1082
  if (this.account)
1074
1083
  return;
1075
- throw new CofhesdkError({
1084
+ throw new CofheError({
1076
1085
  code: "ACCOUNT_UNINITIALIZED" /* AccountUninitialized */,
1077
1086
  message: "Account is not set",
1078
1087
  hint: "Ensure client.connect() has been called and awaited, or use setAccount(...) to set the account explicitly.",
@@ -1083,12 +1092,12 @@ var BaseBuilder = class {
1083
1092
  }
1084
1093
  /**
1085
1094
  * Asserts that this.publicClient is populated
1086
- * @throws {CofhesdkError} If publicClient is not set
1095
+ * @throws {CofheError} If publicClient is not set
1087
1096
  */
1088
1097
  assertPublicClient() {
1089
1098
  if (this.publicClient)
1090
1099
  return;
1091
- throw new CofhesdkError({
1100
+ throw new CofheError({
1092
1101
  code: "MISSING_PUBLIC_CLIENT" /* MissingPublicClient */,
1093
1102
  message: "Public client not found",
1094
1103
  hint: "Ensure client.connect() has been called with a publicClient.",
@@ -1099,12 +1108,12 @@ var BaseBuilder = class {
1099
1108
  }
1100
1109
  /**
1101
1110
  * Asserts that this.walletClient is populated
1102
- * @throws {CofhesdkError} If walletClient is not set
1111
+ * @throws {CofheError} If walletClient is not set
1103
1112
  */
1104
1113
  assertWalletClient() {
1105
1114
  if (this.walletClient)
1106
1115
  return;
1107
- throw new CofhesdkError({
1116
+ throw new CofheError({
1108
1117
  code: "MISSING_WALLET_CLIENT" /* MissingWalletClient */,
1109
1118
  message: "Wallet client not found",
1110
1119
  hint: "Ensure client.connect() has been called with a walletClient.",
@@ -1149,7 +1158,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1149
1158
  this.securityZone = params.securityZone ?? 0;
1150
1159
  this.zkvWalletClient = params.zkvWalletClient;
1151
1160
  if (!params.tfhePublicKeyDeserializer) {
1152
- throw new CofhesdkError({
1161
+ throw new CofheError({
1153
1162
  code: "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER" /* MissingTfhePublicKeyDeserializer */,
1154
1163
  message: "EncryptInputsBuilder tfhePublicKeyDeserializer is undefined",
1155
1164
  hint: "Ensure client has been created with a tfhePublicKeyDeserializer.",
@@ -1160,7 +1169,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1160
1169
  }
1161
1170
  this.tfhePublicKeyDeserializer = params.tfhePublicKeyDeserializer;
1162
1171
  if (!params.compactPkeCrsDeserializer) {
1163
- throw new CofhesdkError({
1172
+ throw new CofheError({
1164
1173
  code: "MISSING_COMPACT_PKE_CRS_DESERIALIZER" /* MissingCompactPkeCrsDeserializer */,
1165
1174
  message: "EncryptInputsBuilder compactPkeCrsDeserializer is undefined",
1166
1175
  hint: "Ensure client has been created with a compactPkeCrsDeserializer.",
@@ -1171,7 +1180,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1171
1180
  }
1172
1181
  this.compactPkeCrsDeserializer = params.compactPkeCrsDeserializer;
1173
1182
  if (!params.zkBuilderAndCrsGenerator) {
1174
- throw new CofhesdkError({
1183
+ throw new CofheError({
1175
1184
  code: "MISSING_ZK_BUILDER_AND_CRS_GENERATOR" /* MissingZkBuilderAndCrsGenerator */,
1176
1185
  message: "EncryptInputsBuilder zkBuilderAndCrsGenerator is undefined",
1177
1186
  hint: "Ensure client has been created with a zkBuilderAndCrsGenerator.",
@@ -1195,7 +1204,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1195
1204
  * ```typescript
1196
1205
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1197
1206
  * .setAccount("0x123")
1198
- * .encrypt();
1207
+ * .execute();
1199
1208
  * ```
1200
1209
  *
1201
1210
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1216,7 +1225,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1216
1225
  * ```typescript
1217
1226
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1218
1227
  * .setChainId(11155111)
1219
- * .encrypt();
1228
+ * .execute();
1220
1229
  * ```
1221
1230
  *
1222
1231
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1237,7 +1246,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1237
1246
  * ```typescript
1238
1247
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1239
1248
  * .setSecurityZone(1)
1240
- * .encrypt();
1249
+ * .execute();
1241
1250
  * ```
1242
1251
  *
1243
1252
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1258,7 +1267,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1258
1267
  * ```typescript
1259
1268
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1260
1269
  * .setUseWorker(false)
1261
- * .encrypt();
1270
+ * .execute();
1262
1271
  * ```
1263
1272
  *
1264
1273
  * @returns The chainable EncryptInputsBuilder instance.
@@ -1292,13 +1301,13 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1292
1301
  * Example:
1293
1302
  * ```typescript
1294
1303
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1295
- * .setStepCallback((step: EncryptStep) => console.log(step))
1296
- * .encrypt();
1304
+ * .onStep((step: EncryptStep) => console.log(step))
1305
+ * .execute();
1297
1306
  * ```
1298
1307
  *
1299
1308
  * @returns The EncryptInputsBuilder instance.
1300
1309
  */
1301
- setStepCallback(callback) {
1310
+ onStep(callback) {
1302
1311
  this.stepCallback = callback;
1303
1312
  return this;
1304
1313
  }
@@ -1321,7 +1330,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1321
1330
  this.stepCallback(step, { ...context, isStart: false, isEnd: true, duration });
1322
1331
  }
1323
1332
  /**
1324
- * zkVerifierUrl is included in the chains exported from cofhesdk/chains for use in CofhesdkConfig.supportedChains
1333
+ * zkVerifierUrl is included in the chains exported from @cofhe/sdk/chains for use in CofheConfig.supportedChains
1325
1334
  * Users should generally not set this manually.
1326
1335
  */
1327
1336
  async getZkVerifierUrl() {
@@ -1329,7 +1338,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1329
1338
  return getZkVerifierUrlOrThrow(this.config, this.chainId);
1330
1339
  }
1331
1340
  /**
1332
- * initTfhe is a platform-specific dependency injected into core/createCofhesdkClientBase by web/createCofhesdkClient and node/createCofhesdkClient
1341
+ * initTfhe is a platform-specific dependency injected into core/createCofheClientBase by web/createCofheClient and node/createCofheClient
1333
1342
  * web/ uses zama "tfhe"
1334
1343
  * node/ uses zama "node-tfhe"
1335
1344
  * Users should not set this manually.
@@ -1340,7 +1349,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1340
1349
  try {
1341
1350
  return await this.initTfhe();
1342
1351
  } catch (error) {
1343
- throw CofhesdkError.fromError(error, {
1352
+ throw CofheError.fromError(error, {
1344
1353
  code: "INIT_TFHE_FAILED" /* InitTfheFailed */,
1345
1354
  message: `Failed to initialize TFHE`,
1346
1355
  context: {
@@ -1359,7 +1368,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1359
1368
  try {
1360
1369
  await this.keysStorage?.rehydrateKeysStore();
1361
1370
  } catch (error) {
1362
- throw CofhesdkError.fromError(error, {
1371
+ throw CofheError.fromError(error, {
1363
1372
  code: "REHYDRATE_KEYS_STORE_FAILED" /* RehydrateKeysStoreFailed */,
1364
1373
  message: `Failed to rehydrate keys store`,
1365
1374
  context: {
@@ -1381,7 +1390,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1381
1390
  this.keysStorage
1382
1391
  );
1383
1392
  } catch (error) {
1384
- throw CofhesdkError.fromError(error, {
1393
+ throw CofheError.fromError(error, {
1385
1394
  code: "FETCH_KEYS_FAILED" /* FetchKeysFailed */,
1386
1395
  message: `Failed to fetch FHE key and CRS`,
1387
1396
  context: {
@@ -1394,7 +1403,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1394
1403
  });
1395
1404
  }
1396
1405
  if (!fheKey) {
1397
- throw new CofhesdkError({
1406
+ throw new CofheError({
1398
1407
  code: "MISSING_FHE_KEY" /* MissingFheKey */,
1399
1408
  message: `FHE key not found`,
1400
1409
  context: {
@@ -1404,7 +1413,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1404
1413
  });
1405
1414
  }
1406
1415
  if (!crs) {
1407
- throw new CofhesdkError({
1416
+ throw new CofheError({
1408
1417
  code: "MISSING_CRS" /* MissingCrs */,
1409
1418
  message: `CRS not found for chainId <${this.chainId}>`,
1410
1419
  context: {
@@ -1414,6 +1423,17 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1414
1423
  }
1415
1424
  return { fheKey, fheKeyFetchedFromCoFHE, crs, crsFetchedFromCoFHE };
1416
1425
  }
1426
+ /**
1427
+ * Resolves the encryptDelay config into an array of 5 per-step delays.
1428
+ * A single number is broadcast to all steps; a tuple is used as-is.
1429
+ */
1430
+ resolveEncryptDelays() {
1431
+ const encryptDelay = this.config?.mocks?.encryptDelay ?? [100, 100, 100, 500, 500];
1432
+ if (typeof encryptDelay === "number") {
1433
+ return [encryptDelay, encryptDelay, encryptDelay, encryptDelay, encryptDelay];
1434
+ }
1435
+ return encryptDelay;
1436
+ }
1417
1437
  /**
1418
1438
  * @dev Encrypt against the cofheMocks instead of CoFHE
1419
1439
  *
@@ -1421,25 +1441,35 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1421
1441
  * cofheMocksInsertPackedHashes - stores the ctHashes and their plaintext values for on-chain mocking of FHE operations.
1422
1442
  * cofheMocksZkCreateProofSignatures - creates signatures to be included in the encrypted inputs. The signers address is known and verified in the mock contracts.
1423
1443
  */
1424
- async mocksEncrypt() {
1444
+ async mocksExecute() {
1425
1445
  this.assertAccount();
1426
1446
  this.assertPublicClient();
1427
1447
  this.assertWalletClient();
1448
+ const [initTfheDelay, fetchKeysDelay, packDelay, proveDelay, verifyDelay] = this.resolveEncryptDelays();
1428
1449
  this.fireStepStart("initTfhe" /* InitTfhe */);
1429
- await sleep(100);
1430
- this.fireStepEnd("initTfhe" /* InitTfhe */, { tfheInitializationExecuted: false });
1450
+ await sleep(initTfheDelay);
1451
+ this.fireStepEnd("initTfhe" /* InitTfhe */, {
1452
+ tfheInitializationExecuted: false,
1453
+ isMocks: true,
1454
+ mockSleep: initTfheDelay
1455
+ });
1431
1456
  this.fireStepStart("fetchKeys" /* FetchKeys */);
1432
- await sleep(100);
1433
- this.fireStepEnd("fetchKeys" /* FetchKeys */, { fheKeyFetchedFromCoFHE: false, crsFetchedFromCoFHE: false });
1457
+ await sleep(fetchKeysDelay);
1458
+ this.fireStepEnd("fetchKeys" /* FetchKeys */, {
1459
+ fheKeyFetchedFromCoFHE: false,
1460
+ crsFetchedFromCoFHE: false,
1461
+ isMocks: true,
1462
+ mockSleep: fetchKeysDelay
1463
+ });
1434
1464
  this.fireStepStart("pack" /* Pack */);
1435
1465
  await cofheMocksCheckEncryptableBits(this.inputItems);
1436
- await sleep(100);
1437
- this.fireStepEnd("pack" /* Pack */);
1466
+ await sleep(packDelay);
1467
+ this.fireStepEnd("pack" /* Pack */, { isMocks: true, mockSleep: packDelay });
1438
1468
  this.fireStepStart("prove" /* Prove */);
1439
- await sleep(500);
1440
- this.fireStepEnd("prove" /* Prove */);
1469
+ await sleep(proveDelay);
1470
+ this.fireStepEnd("prove" /* Prove */, { isMocks: true, mockSleep: proveDelay });
1441
1471
  this.fireStepStart("verify" /* Verify */);
1442
- await sleep(500);
1472
+ await sleep(verifyDelay);
1443
1473
  const signedResults = await cofheMocksZkVerifySign(
1444
1474
  this.inputItems,
1445
1475
  this.account,
@@ -1454,13 +1484,13 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1454
1484
  utype: this.inputItems[index].utype,
1455
1485
  signature
1456
1486
  }));
1457
- this.fireStepEnd("verify" /* Verify */);
1487
+ this.fireStepEnd("verify" /* Verify */, { isMocks: true, mockSleep: verifyDelay });
1458
1488
  return encryptedInputs;
1459
1489
  }
1460
1490
  /**
1461
1491
  * In the production context, perform a true encryption with the CoFHE coprocessor.
1462
1492
  */
1463
- async productionEncrypt() {
1493
+ async productionExecute() {
1464
1494
  this.assertAccount();
1465
1495
  this.assertChainId();
1466
1496
  this.fireStepStart("initTfhe" /* InitTfhe */);
@@ -1523,15 +1553,15 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1523
1553
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1524
1554
  * .setAccount('0x123...890') // optional
1525
1555
  * .setChainId(11155111) // optional
1526
- * .encrypt(); // execute
1556
+ * .execute(); // execute
1527
1557
  * ```
1528
1558
  *
1529
1559
  * @returns The encrypted inputs.
1530
1560
  */
1531
- async encrypt() {
1561
+ async execute() {
1532
1562
  if (this.chainId === chains.hardhat.id)
1533
- return this.mocksEncrypt();
1534
- return this.productionEncrypt();
1563
+ return this.mocksExecute();
1564
+ return this.productionExecute();
1535
1565
  }
1536
1566
  };
1537
1567
 
@@ -1582,9 +1612,6 @@ function isBigIntOrNumber(value) {
1582
1612
  }
1583
1613
  }
1584
1614
  }
1585
- function is0xPrefixed(value) {
1586
- return value.startsWith("0x");
1587
- }
1588
1615
 
1589
1616
  // permits/sealing.ts
1590
1617
  var PRIVATE_KEY_LENGTH = 64;
@@ -1672,158 +1699,137 @@ var SerializedSealingPair = zod.z.object({
1672
1699
  privateKey: zod.z.string(),
1673
1700
  publicKey: zod.z.string()
1674
1701
  });
1702
+ var addressSchema = zod.z.string().refine((val) => viem.isAddress(val), {
1703
+ error: "Invalid address"
1704
+ }).transform((val) => viem.getAddress(val));
1705
+ var addressNotZeroSchema = addressSchema.refine((val) => val !== viem.zeroAddress, {
1706
+ error: "Must not be zeroAddress"
1707
+ });
1708
+ var bytesSchema = zod.z.custom(
1709
+ (val) => {
1710
+ return typeof val === "string" && viem.isHex(val);
1711
+ },
1712
+ {
1713
+ message: "Invalid hex value"
1714
+ }
1715
+ );
1716
+ var bytesNotEmptySchema = bytesSchema.refine((val) => val !== "0x", {
1717
+ error: "Must not be empty"
1718
+ });
1675
1719
  var DEFAULT_EXPIRATION_FN = () => Math.round(Date.now() / 1e3) + 7 * 24 * 60 * 60;
1676
1720
  var zPermitWithDefaults = zod.z.object({
1677
1721
  name: zod.z.string().optional().default("Unnamed Permit"),
1678
1722
  type: zod.z.enum(["self", "sharing", "recipient"]),
1679
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1680
- message: "Permit issuer :: invalid address"
1681
- }).refine((val) => val !== viem.zeroAddress, {
1682
- message: "Permit issuer :: must not be zeroAddress"
1683
- }),
1684
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1685
- recipient: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1686
- message: "Permit recipient :: invalid address"
1687
- }),
1688
- validatorId: zod.z.number().optional().default(0),
1689
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1690
- message: "Permit validatorContract :: invalid address"
1691
- }),
1692
- issuerSignature: zod.z.string().optional().default("0x"),
1693
- recipientSignature: zod.z.string().optional().default("0x")
1723
+ issuer: addressNotZeroSchema,
1724
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1725
+ recipient: addressSchema.optional().default(viem.zeroAddress),
1726
+ validatorId: zod.z.int().optional().default(0),
1727
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1728
+ issuerSignature: bytesSchema.optional().default("0x"),
1729
+ recipientSignature: bytesSchema.optional().default("0x")
1694
1730
  });
1695
1731
  var zPermitWithSealingPair = zPermitWithDefaults.extend({
1696
1732
  sealingPair: SerializedSealingPair.optional()
1697
1733
  });
1698
- var ValidatorContractRefinement = [
1734
+ var ExternalValidatorRefinement = [
1699
1735
  (data) => data.validatorId !== 0 && data.validatorContract !== viem.zeroAddress || data.validatorId === 0 && data.validatorContract === viem.zeroAddress,
1700
1736
  {
1701
- message: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
1737
+ error: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
1702
1738
  path: ["validatorId", "validatorContract"]
1703
1739
  }
1704
1740
  ];
1741
+ var RecipientRefinement = [
1742
+ (data) => data.issuer !== data.recipient,
1743
+ {
1744
+ error: "Sharing permit :: issuer and recipient must not be the same",
1745
+ path: ["issuer", "recipient"]
1746
+ }
1747
+ ];
1705
1748
  var SelfPermitOptionsValidator = zod.z.object({
1706
1749
  type: zod.z.literal("self").optional().default("self"),
1707
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1708
- message: "Self permit issuer :: invalid address"
1709
- }).refine((val) => is0xPrefixed(val), {
1710
- message: "Self permit issuer :: must be 0x prefixed"
1711
- }).refine((val) => val !== viem.zeroAddress, {
1712
- message: "Self permit issuer :: must not be zeroAddress"
1713
- }),
1750
+ issuer: addressNotZeroSchema,
1714
1751
  name: zod.z.string().optional().default("Unnamed Permit"),
1715
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1716
- recipient: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1717
- message: "Self permit recipient :: invalid address"
1718
- }).refine((val) => is0xPrefixed(val), {
1719
- message: "Self permit recipient :: must be 0x prefixed"
1720
- }).refine((val) => val === viem.zeroAddress, {
1721
- message: "Self permit recipient :: must be zeroAddress"
1722
- }),
1723
- validatorId: zod.z.number().optional().default(0),
1724
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1725
- message: "Self permit validatorContract :: invalid address"
1726
- }),
1727
- issuerSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1728
- message: "Self permit issuerSignature :: must be 0x prefixed"
1729
- }),
1730
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1731
- message: "Self permit recipientSignature :: must be 0x prefixed"
1732
- })
1733
- }).refine(...ValidatorContractRefinement);
1752
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1753
+ recipient: addressSchema.optional().default(viem.zeroAddress),
1754
+ validatorId: zod.z.int().optional().default(0),
1755
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1756
+ issuerSignature: bytesSchema.optional().default("0x"),
1757
+ recipientSignature: bytesSchema.optional().default("0x")
1758
+ }).refine(...ExternalValidatorRefinement);
1734
1759
  var SelfPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "self", {
1735
- message: "Self permit :: type must be 'self'"
1760
+ error: "Type must be 'self'"
1736
1761
  }).refine((data) => data.recipient === viem.zeroAddress, {
1737
- message: "Self permit :: recipient must be zeroAddress"
1762
+ error: "Recipient must be zeroAddress"
1738
1763
  }).refine((data) => data.issuerSignature !== "0x", {
1739
- message: "Self permit :: issuerSignature must be populated"
1764
+ error: "IssuerSignature must be populated"
1740
1765
  }).refine((data) => data.recipientSignature === "0x", {
1741
- message: "Self permit :: recipientSignature must be empty"
1742
- }).refine(...ValidatorContractRefinement);
1766
+ error: "RecipientSignature must be empty"
1767
+ }).refine(...ExternalValidatorRefinement);
1743
1768
  var SharingPermitOptionsValidator = zod.z.object({
1744
1769
  type: zod.z.literal("sharing").optional().default("sharing"),
1745
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1746
- message: "Sharing permit issuer :: invalid address"
1747
- }).refine((val) => is0xPrefixed(val), {
1748
- message: "Sharing permit issuer :: must be 0x prefixed"
1749
- }).refine((val) => val !== viem.zeroAddress, {
1750
- message: "Sharing permit issuer :: must not be zeroAddress"
1751
- }),
1752
- recipient: zod.z.string().refine((val) => viem.isAddress(val), {
1753
- message: "Sharing permit recipient :: invalid address"
1754
- }).refine((val) => is0xPrefixed(val), {
1755
- message: "Sharing permit recipient :: must be 0x prefixed"
1756
- }).refine((val) => val !== viem.zeroAddress, {
1757
- message: "Sharing permit recipient :: must not be zeroAddress"
1758
- }),
1770
+ issuer: addressNotZeroSchema,
1771
+ recipient: addressNotZeroSchema,
1759
1772
  name: zod.z.string().optional().default("Unnamed Permit"),
1760
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1761
- validatorId: zod.z.number().optional().default(0),
1762
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1763
- message: "Sharing permit validatorContract :: invalid address"
1764
- }),
1765
- issuerSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1766
- message: "Sharing permit issuerSignature :: must be 0x prefixed"
1767
- }),
1768
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1769
- message: "Sharing permit recipientSignature :: must be 0x prefixed"
1770
- })
1771
- }).refine(...ValidatorContractRefinement);
1773
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1774
+ validatorId: zod.z.int().optional().default(0),
1775
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1776
+ issuerSignature: bytesSchema.optional().default("0x"),
1777
+ recipientSignature: bytesSchema.optional().default("0x")
1778
+ }).refine(...RecipientRefinement).refine(...ExternalValidatorRefinement);
1772
1779
  var SharingPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "sharing", {
1773
- message: "Sharing permit :: type must be 'sharing'"
1780
+ error: "Type must be 'sharing'"
1774
1781
  }).refine((data) => data.recipient !== viem.zeroAddress, {
1775
- message: "Sharing permit :: recipient must not be zeroAddress"
1782
+ error: "Recipient must not be zeroAddress"
1776
1783
  }).refine((data) => data.issuerSignature !== "0x", {
1777
- message: "Sharing permit :: issuerSignature must be populated"
1784
+ error: "IssuerSignature must be populated"
1778
1785
  }).refine((data) => data.recipientSignature === "0x", {
1779
- message: "Sharing permit :: recipientSignature must be empty"
1780
- }).refine(...ValidatorContractRefinement);
1786
+ error: "RecipientSignature must be empty"
1787
+ }).refine(...ExternalValidatorRefinement);
1781
1788
  var ImportPermitOptionsValidator = zod.z.object({
1782
1789
  type: zod.z.literal("recipient").optional().default("recipient"),
1783
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1784
- message: "Import permit issuer :: invalid address"
1785
- }).refine((val) => is0xPrefixed(val), {
1786
- message: "Import permit issuer :: must be 0x prefixed"
1787
- }).refine((val) => val !== viem.zeroAddress, {
1788
- message: "Import permit issuer :: must not be zeroAddress"
1789
- }),
1790
- recipient: zod.z.string().refine((val) => viem.isAddress(val), {
1791
- message: "Import permit recipient :: invalid address"
1792
- }).refine((val) => is0xPrefixed(val), {
1793
- message: "Import permit recipient :: must be 0x prefixed"
1794
- }).refine((val) => val !== viem.zeroAddress, {
1795
- message: "Import permit recipient :: must not be zeroAddress"
1796
- }),
1797
- issuerSignature: zod.z.string().refine((val) => is0xPrefixed(val), {
1798
- message: "Import permit issuerSignature :: must be 0x prefixed"
1799
- }).refine((val) => val !== "0x", {
1800
- message: "Import permit :: issuerSignature must be provided"
1801
- }),
1790
+ issuer: addressNotZeroSchema,
1791
+ recipient: addressNotZeroSchema,
1802
1792
  name: zod.z.string().optional().default("Unnamed Permit"),
1803
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1804
- validatorId: zod.z.number().optional().default(0),
1805
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1806
- message: "Import permit validatorContract :: invalid address"
1807
- }),
1808
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1809
- message: "Import permit recipientSignature :: must be 0x prefixed"
1810
- })
1811
- }).refine(...ValidatorContractRefinement);
1793
+ expiration: zod.z.int(),
1794
+ validatorId: zod.z.int().optional().default(0),
1795
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1796
+ issuerSignature: bytesNotEmptySchema,
1797
+ recipientSignature: bytesSchema.optional().default("0x")
1798
+ }).refine(...ExternalValidatorRefinement);
1812
1799
  var ImportPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "recipient", {
1813
- message: "Import permit :: type must be 'recipient'"
1800
+ error: "Type must be 'recipient'"
1814
1801
  }).refine((data) => data.recipient !== viem.zeroAddress, {
1815
- message: "Import permit :: recipient must not be zeroAddress"
1802
+ error: "Recipient must not be zeroAddress"
1816
1803
  }).refine((data) => data.issuerSignature !== "0x", {
1817
- message: "Import permit :: issuerSignature must be populated"
1804
+ error: "IssuerSignature must be populated"
1818
1805
  }).refine((data) => data.recipientSignature !== "0x", {
1819
- message: "Import permit :: recipientSignature must be populated"
1820
- }).refine(...ValidatorContractRefinement);
1821
- var validateSelfPermitOptions = (options) => SelfPermitOptionsValidator.safeParse(options);
1822
- var validateSharingPermitOptions = (options) => SharingPermitOptionsValidator.safeParse(options);
1823
- var validateImportPermitOptions = (options) => ImportPermitOptionsValidator.safeParse(options);
1824
- var validateSelfPermit = (permit) => SelfPermitValidator.safeParse(permit);
1825
- var validateSharingPermit = (permit) => SharingPermitValidator.safeParse(permit);
1826
- var validateImportPermit = (permit) => ImportPermitValidator.safeParse(permit);
1806
+ error: "RecipientSignature must be populated"
1807
+ }).refine(...ExternalValidatorRefinement);
1808
+ var safeParseAndThrowFormatted = (schema, data, message) => {
1809
+ const result = schema.safeParse(data);
1810
+ if (!result.success) {
1811
+ throw new Error(`${message}: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
1812
+ }
1813
+ return result.data;
1814
+ };
1815
+ var validateSelfPermitOptions = (options) => {
1816
+ return safeParseAndThrowFormatted(SelfPermitOptionsValidator, options, "Invalid self permit options");
1817
+ };
1818
+ var validateSharingPermitOptions = (options) => {
1819
+ return safeParseAndThrowFormatted(SharingPermitOptionsValidator, options, "Invalid sharing permit options");
1820
+ };
1821
+ var validateImportPermitOptions = (options) => {
1822
+ return safeParseAndThrowFormatted(ImportPermitOptionsValidator, options, "Invalid import permit options");
1823
+ };
1824
+ var validateSelfPermit = (permit) => {
1825
+ return safeParseAndThrowFormatted(SelfPermitValidator, permit, "Invalid self permit");
1826
+ };
1827
+ var validateSharingPermit = (permit) => {
1828
+ return safeParseAndThrowFormatted(SharingPermitValidator, permit, "Invalid sharing permit");
1829
+ };
1830
+ var validateImportPermit = (permit) => {
1831
+ return safeParseAndThrowFormatted(ImportPermitValidator, permit, "Invalid import permit");
1832
+ };
1827
1833
  var ValidationUtils = {
1828
1834
  /**
1829
1835
  * Check if permit is expired
@@ -1917,6 +1923,179 @@ var SignatureUtils = {
1917
1923
  throw new Error(`Unknown permit type: ${permitType}`);
1918
1924
  }
1919
1925
  };
1926
+ var getAclAddress = async (publicClient) => {
1927
+ const ACL_IFACE = "function acl() view returns (address)";
1928
+ const aclAbi = viem.parseAbi([ACL_IFACE]);
1929
+ return await publicClient.readContract({
1930
+ address: TASK_MANAGER_ADDRESS,
1931
+ abi: aclAbi,
1932
+ functionName: "acl"
1933
+ });
1934
+ };
1935
+ var getAclEIP712Domain = async (publicClient) => {
1936
+ const aclAddress = await getAclAddress(publicClient);
1937
+ const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
1938
+ const domainAbi = viem.parseAbi([EIP712_DOMAIN_IFACE]);
1939
+ const domain = await publicClient.readContract({
1940
+ address: aclAddress,
1941
+ abi: domainAbi,
1942
+ functionName: "eip712Domain"
1943
+ });
1944
+ const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
1945
+ return {
1946
+ name,
1947
+ version,
1948
+ chainId: Number(chainId),
1949
+ verifyingContract
1950
+ };
1951
+ };
1952
+ var checkPermitValidityOnChain = async (permission, publicClient) => {
1953
+ const aclAddress = await getAclAddress(publicClient);
1954
+ try {
1955
+ await publicClient.simulateContract({
1956
+ address: aclAddress,
1957
+ abi: checkPermitValidityAbi,
1958
+ functionName: "checkPermitValidity",
1959
+ args: [
1960
+ {
1961
+ issuer: permission.issuer,
1962
+ expiration: BigInt(permission.expiration),
1963
+ recipient: permission.recipient,
1964
+ validatorId: BigInt(permission.validatorId),
1965
+ validatorContract: permission.validatorContract,
1966
+ sealingKey: permission.sealingKey,
1967
+ issuerSignature: permission.issuerSignature,
1968
+ recipientSignature: permission.recipientSignature
1969
+ }
1970
+ ]
1971
+ });
1972
+ return true;
1973
+ } catch (err) {
1974
+ if (err instanceof viem.BaseError) {
1975
+ const revertError = err.walk((err2) => err2 instanceof viem.ContractFunctionRevertedError);
1976
+ if (revertError instanceof viem.ContractFunctionRevertedError) {
1977
+ const errorName = revertError.data?.errorName ?? "";
1978
+ throw new Error(errorName);
1979
+ }
1980
+ }
1981
+ const customErrorName = extractCustomErrorFromDetails(err, checkPermitValidityAbi);
1982
+ if (customErrorName) {
1983
+ throw new Error(customErrorName);
1984
+ }
1985
+ const hhDetailsData = extractReturnData(err);
1986
+ if (hhDetailsData != null) {
1987
+ const decoded = viem.decodeErrorResult({
1988
+ abi: checkPermitValidityAbi,
1989
+ data: hhDetailsData
1990
+ });
1991
+ throw new Error(decoded.errorName);
1992
+ }
1993
+ throw err;
1994
+ }
1995
+ };
1996
+ function extractCustomErrorFromDetails(err, abi) {
1997
+ const anyErr = err;
1998
+ const details = anyErr?.details ?? anyErr?.cause?.details;
1999
+ if (typeof details === "string") {
2000
+ const customErrorMatch = details.match(/reverted with custom error '(\w+)\(\)'/);
2001
+ if (customErrorMatch) {
2002
+ const errorName = customErrorMatch[1];
2003
+ const errorExists = abi.some((item) => item.type === "error" && item.name === errorName);
2004
+ if (errorExists) {
2005
+ return errorName;
2006
+ }
2007
+ }
2008
+ }
2009
+ return void 0;
2010
+ }
2011
+ function extractReturnData(err) {
2012
+ const anyErr = err;
2013
+ const s = anyErr?.details ?? anyErr?.cause?.details ?? anyErr?.shortMessage ?? anyErr?.message ?? String(err);
2014
+ return s.match(/return data:\s*(0x[a-fA-F0-9]+)/)?.[1];
2015
+ }
2016
+ var checkPermitValidityAbi = [
2017
+ {
2018
+ type: "function",
2019
+ name: "checkPermitValidity",
2020
+ inputs: [
2021
+ {
2022
+ name: "permission",
2023
+ type: "tuple",
2024
+ internalType: "struct Permission",
2025
+ components: [
2026
+ {
2027
+ name: "issuer",
2028
+ type: "address",
2029
+ internalType: "address"
2030
+ },
2031
+ {
2032
+ name: "expiration",
2033
+ type: "uint64",
2034
+ internalType: "uint64"
2035
+ },
2036
+ {
2037
+ name: "recipient",
2038
+ type: "address",
2039
+ internalType: "address"
2040
+ },
2041
+ {
2042
+ name: "validatorId",
2043
+ type: "uint256",
2044
+ internalType: "uint256"
2045
+ },
2046
+ {
2047
+ name: "validatorContract",
2048
+ type: "address",
2049
+ internalType: "address"
2050
+ },
2051
+ {
2052
+ name: "sealingKey",
2053
+ type: "bytes32",
2054
+ internalType: "bytes32"
2055
+ },
2056
+ {
2057
+ name: "issuerSignature",
2058
+ type: "bytes",
2059
+ internalType: "bytes"
2060
+ },
2061
+ {
2062
+ name: "recipientSignature",
2063
+ type: "bytes",
2064
+ internalType: "bytes"
2065
+ }
2066
+ ]
2067
+ }
2068
+ ],
2069
+ outputs: [
2070
+ {
2071
+ name: "",
2072
+ type: "bool",
2073
+ internalType: "bool"
2074
+ }
2075
+ ],
2076
+ stateMutability: "view"
2077
+ },
2078
+ {
2079
+ type: "error",
2080
+ name: "PermissionInvalid_Disabled",
2081
+ inputs: []
2082
+ },
2083
+ {
2084
+ type: "error",
2085
+ name: "PermissionInvalid_Expired",
2086
+ inputs: []
2087
+ },
2088
+ {
2089
+ type: "error",
2090
+ name: "PermissionInvalid_IssuerSignature",
2091
+ inputs: []
2092
+ },
2093
+ {
2094
+ type: "error",
2095
+ name: "PermissionInvalid_RecipientSignature",
2096
+ inputs: []
2097
+ }
2098
+ ];
1920
2099
 
1921
2100
  // permits/permit.ts
1922
2101
  var PermitUtils = {
@@ -1925,14 +2104,10 @@ var PermitUtils = {
1925
2104
  */
1926
2105
  createSelf: (options) => {
1927
2106
  const validation = validateSelfPermitOptions(options);
1928
- if (!validation.success) {
1929
- throw new Error(
1930
- "PermitUtils :: createSelf :: Parsing SelfPermitOptions failed " + JSON.stringify(validation.error, null, 2)
1931
- );
1932
- }
1933
2107
  const sealingPair = GenerateSealingKey();
1934
2108
  const permit = {
1935
- ...validation.data,
2109
+ hash: PermitUtils.getHash(validation),
2110
+ ...validation,
1936
2111
  sealingPair,
1937
2112
  _signedDomain: void 0
1938
2113
  };
@@ -1943,14 +2118,10 @@ var PermitUtils = {
1943
2118
  */
1944
2119
  createSharing: (options) => {
1945
2120
  const validation = validateSharingPermitOptions(options);
1946
- if (!validation.success) {
1947
- throw new Error(
1948
- "PermitUtils :: createSharing :: Parsing SharingPermitOptions failed " + JSON.stringify(validation.error, null, 2)
1949
- );
1950
- }
1951
2121
  const sealingPair = GenerateSealingKey();
1952
2122
  const permit = {
1953
- ...validation.data,
2123
+ hash: PermitUtils.getHash(validation),
2124
+ ...validation,
1954
2125
  sealingPair,
1955
2126
  _signedDomain: void 0
1956
2127
  };
@@ -1965,27 +2136,21 @@ var PermitUtils = {
1965
2136
  try {
1966
2137
  parsedOptions = JSON.parse(options);
1967
2138
  } catch (error) {
1968
- throw new Error(`PermitUtils :: importShared :: Failed to parse JSON string: ${error}`);
2139
+ throw new Error(`Failed to parse JSON string: ${error}`);
1969
2140
  }
1970
2141
  } else if (typeof options === "object" && options !== null) {
1971
2142
  parsedOptions = options;
1972
2143
  } else {
1973
- throw new Error(
1974
- "PermitUtils :: importShared :: Invalid input type, expected ImportSharedPermitOptions, object, or string"
1975
- );
2144
+ throw new Error("Invalid input type, expected ImportSharedPermitOptions, object, or string");
1976
2145
  }
1977
2146
  if (parsedOptions.type != null && parsedOptions.type !== "sharing") {
1978
- throw new Error(`PermitUtils :: importShared :: Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
2147
+ throw new Error(`Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
1979
2148
  }
1980
2149
  const validation = validateImportPermitOptions({ ...parsedOptions, type: "recipient" });
1981
- if (!validation.success) {
1982
- throw new Error(
1983
- "PermitUtils :: importShared :: Parsing ImportPermitOptions failed " + JSON.stringify(validation.error, null, 2)
1984
- );
1985
- }
1986
2150
  const sealingPair = GenerateSealingKey();
1987
2151
  const permit = {
1988
- ...validation.data,
2152
+ hash: PermitUtils.getHash(validation),
2153
+ ...validation,
1989
2154
  sealingPair,
1990
2155
  _signedDomain: void 0
1991
2156
  };
@@ -1997,11 +2162,11 @@ var PermitUtils = {
1997
2162
  sign: async (permit, publicClient, walletClient) => {
1998
2163
  if (walletClient == null || walletClient.account == null) {
1999
2164
  throw new Error(
2000
- "PermitUtils :: sign - walletClient undefined, you must pass in a `walletClient` for the connected user to create a permit signature"
2165
+ "Missing walletClient, you must pass in a `walletClient` for the connected user to create a permit signature"
2001
2166
  );
2002
2167
  }
2003
2168
  const primaryType = SignatureUtils.getPrimaryType(permit.type);
2004
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
2169
+ const domain = await getAclEIP712Domain(publicClient);
2005
2170
  const { types, message } = SignatureUtils.getSignatureParams(PermitUtils.getPermission(permit, true), primaryType);
2006
2171
  const signature = await walletClient.signTypedData({
2007
2172
  domain,
@@ -2061,6 +2226,7 @@ var PermitUtils = {
2061
2226
  */
2062
2227
  serialize: (permit) => {
2063
2228
  return {
2229
+ hash: permit.hash,
2064
2230
  name: permit.name,
2065
2231
  type: permit.type,
2066
2232
  issuer: permit.issuer,
@@ -2085,7 +2251,7 @@ var PermitUtils = {
2085
2251
  } else if (permit.type === "recipient") {
2086
2252
  return validateImportPermit(permit);
2087
2253
  } else {
2088
- throw new Error("PermitUtils :: validate :: Invalid permit type");
2254
+ throw new Error("Invalid permit type");
2089
2255
  }
2090
2256
  },
2091
2257
  /**
@@ -2093,12 +2259,7 @@ var PermitUtils = {
2093
2259
  */
2094
2260
  getPermission: (permit, skipValidation = false) => {
2095
2261
  if (!skipValidation) {
2096
- const validationResult = PermitUtils.validate(permit);
2097
- if (!validationResult.success) {
2098
- throw new Error(
2099
- `PermitUtils :: getPermission :: permit validation failed - ${JSON.stringify(validationResult.error, null, 2)} ${JSON.stringify(permit, null, 2)}`
2100
- );
2101
- }
2262
+ PermitUtils.validate(permit);
2102
2263
  }
2103
2264
  return {
2104
2265
  issuer: permit.issuer,
@@ -2179,28 +2340,7 @@ var PermitUtils = {
2179
2340
  * Fetch EIP712 domain from the blockchain
2180
2341
  */
2181
2342
  fetchEIP712Domain: async (publicClient) => {
2182
- const TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
2183
- const ACL_IFACE = "function acl() view returns (address)";
2184
- const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
2185
- const aclAbi = viem.parseAbi([ACL_IFACE]);
2186
- const aclAddress = await publicClient.readContract({
2187
- address: TASK_MANAGER_ADDRESS,
2188
- abi: aclAbi,
2189
- functionName: "acl"
2190
- });
2191
- const domainAbi = viem.parseAbi([EIP712_DOMAIN_IFACE]);
2192
- const domain = await publicClient.readContract({
2193
- address: aclAddress,
2194
- abi: domainAbi,
2195
- functionName: "eip712Domain"
2196
- });
2197
- const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
2198
- return {
2199
- name,
2200
- version,
2201
- chainId: Number(chainId),
2202
- verifyingContract
2203
- };
2343
+ return getAclEIP712Domain(publicClient);
2204
2344
  },
2205
2345
  /**
2206
2346
  * Check if permit's signed domain matches the provided domain
@@ -2214,8 +2354,15 @@ var PermitUtils = {
2214
2354
  checkSignedDomainValid: async (permit, publicClient) => {
2215
2355
  if (permit._signedDomain == null)
2216
2356
  return false;
2217
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
2357
+ const domain = await getAclEIP712Domain(publicClient);
2218
2358
  return PermitUtils.matchesDomain(permit, domain);
2359
+ },
2360
+ /**
2361
+ * Check if permit passes the on-chain validation
2362
+ */
2363
+ checkValidityOnChain: async (permit, publicClient) => {
2364
+ const permission = PermitUtils.getPermission(permit);
2365
+ return checkPermitValidityOnChain(permission, publicClient);
2219
2366
  }
2220
2367
  };
2221
2368
  var PERMIT_STORE_DEFAULTS = {
@@ -2269,11 +2416,11 @@ var setPermit = (chainId, account, permit) => {
2269
2416
  state.permits[chainId] = {};
2270
2417
  if (state.permits[chainId][account] == null)
2271
2418
  state.permits[chainId][account] = {};
2272
- state.permits[chainId][account][PermitUtils.getHash(permit)] = PermitUtils.serialize(permit);
2419
+ state.permits[chainId][account][permit.hash] = PermitUtils.serialize(permit);
2273
2420
  })
2274
2421
  );
2275
2422
  };
2276
- var removePermit = (chainId, account, hash, force) => {
2423
+ var removePermit = (chainId, account, hash) => {
2277
2424
  clearStaleStore();
2278
2425
  _permitStore.setState(
2279
2426
  immer.produce((state) => {
@@ -2287,15 +2434,7 @@ var removePermit = (chainId, account, hash, force) => {
2287
2434
  if (accountPermits[hash] == null)
2288
2435
  return;
2289
2436
  if (state.activePermitHash[chainId][account] === hash) {
2290
- const otherPermitHash = Object.keys(accountPermits).find((key) => key !== hash && accountPermits[key] != null);
2291
- if (otherPermitHash) {
2292
- state.activePermitHash[chainId][account] = otherPermitHash;
2293
- } else {
2294
- if (!force) {
2295
- throw new Error("Cannot remove the last permit without force flag");
2296
- }
2297
- state.activePermitHash[chainId][account] = void 0;
2298
- }
2437
+ state.activePermitHash[chainId][account] = void 0;
2299
2438
  }
2300
2439
  accountPermits[hash] = void 0;
2301
2440
  })
@@ -2346,7 +2485,7 @@ var storeActivePermit = async (permit, publicClient, walletClient) => {
2346
2485
  const chainId = await publicClient.getChainId();
2347
2486
  const account = walletClient.account.address;
2348
2487
  permitStore.setPermit(chainId, account, permit);
2349
- permitStore.setActivePermitHash(chainId, account, PermitUtils.getHash(permit));
2488
+ permitStore.setActivePermitHash(chainId, account, permit.hash);
2350
2489
  };
2351
2490
  var createPermitWithSign = async (options, publicClient, walletClient, permitMethod) => {
2352
2491
  const permit = await permitMethod(options, publicClient, walletClient);
@@ -2404,7 +2543,7 @@ var getOrCreateSharingPermit = async (publicClient, walletClient, options, chain
2404
2543
  }
2405
2544
  return createSharing(options, publicClient, walletClient);
2406
2545
  };
2407
- var removePermit2 = async (chainId, account, hash, force) => permitStore.removePermit(chainId, account, hash, force);
2546
+ var removePermit2 = async (chainId, account, hash) => permitStore.removePermit(chainId, account, hash);
2408
2547
  var removeActivePermit = async (chainId, account) => permitStore.removeActivePermitHash(chainId, account);
2409
2548
  var permits = {
2410
2549
  getSnapshot: permitStore.store.getState,
@@ -2444,8 +2583,8 @@ var convertViaUtype = (utype, value) => {
2444
2583
  }
2445
2584
  };
2446
2585
 
2447
- // core/decrypt/MockQueryDecrypterAbi.ts
2448
- var MockQueryDecrypterAbi = [
2586
+ // core/decrypt/MockThresholdNetworkAbi.ts
2587
+ var MockThresholdNetworkAbi = [
2449
2588
  {
2450
2589
  type: "function",
2451
2590
  name: "acl",
@@ -2492,11 +2631,7 @@ var MockQueryDecrypterAbi = [
2492
2631
  { name: "expiration", type: "uint64", internalType: "uint64" },
2493
2632
  { name: "recipient", type: "address", internalType: "address" },
2494
2633
  { name: "validatorId", type: "uint256", internalType: "uint256" },
2495
- {
2496
- name: "validatorContract",
2497
- type: "address",
2498
- internalType: "address"
2499
- },
2634
+ { name: "validatorContract", type: "address", internalType: "address" },
2500
2635
  { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2501
2636
  { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2502
2637
  { name: "recipientSignature", type: "bytes", internalType: "bytes" }
@@ -2525,11 +2660,7 @@ var MockQueryDecrypterAbi = [
2525
2660
  { name: "expiration", type: "uint64", internalType: "uint64" },
2526
2661
  { name: "recipient", type: "address", internalType: "address" },
2527
2662
  { name: "validatorId", type: "uint256", internalType: "uint256" },
2528
- {
2529
- name: "validatorContract",
2530
- type: "address",
2531
- internalType: "address"
2532
- },
2663
+ { name: "validatorContract", type: "address", internalType: "address" },
2533
2664
  { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2534
2665
  { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2535
2666
  { name: "recipientSignature", type: "bytes", internalType: "bytes" }
@@ -2553,13 +2684,6 @@ var MockQueryDecrypterAbi = [
2553
2684
  outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
2554
2685
  stateMutability: "pure"
2555
2686
  },
2556
- {
2557
- type: "function",
2558
- name: "taskManager",
2559
- inputs: [],
2560
- outputs: [{ name: "", type: "address", internalType: "contract TaskManager" }],
2561
- stateMutability: "view"
2562
- },
2563
2687
  {
2564
2688
  type: "function",
2565
2689
  name: "unseal",
@@ -2570,16 +2694,80 @@ var MockQueryDecrypterAbi = [
2570
2694
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
2571
2695
  stateMutability: "pure"
2572
2696
  },
2573
- { type: "error", name: "NotAllowed", inputs: [] },
2574
- { type: "error", name: "SealingKeyInvalid", inputs: [] },
2575
- { type: "error", name: "SealingKeyMissing", inputs: [] }
2697
+ {
2698
+ type: "function",
2699
+ name: "mockAcl",
2700
+ inputs: [],
2701
+ outputs: [{ name: "", type: "address", internalType: "contract MockACL" }],
2702
+ stateMutability: "view"
2703
+ },
2704
+ {
2705
+ type: "function",
2706
+ name: "mockTaskManager",
2707
+ inputs: [],
2708
+ outputs: [{ name: "", type: "address", internalType: "contract MockTaskManager" }],
2709
+ stateMutability: "view"
2710
+ },
2711
+ {
2712
+ type: "function",
2713
+ name: "mockQueryDecrypt",
2714
+ inputs: [
2715
+ { name: "ctHash", type: "uint256", internalType: "uint256" },
2716
+ { name: "", type: "uint256", internalType: "uint256" },
2717
+ { name: "issuer", type: "address", internalType: "address" }
2718
+ ],
2719
+ outputs: [
2720
+ { name: "allowed", type: "bool", internalType: "bool" },
2721
+ { name: "error", type: "string", internalType: "string" },
2722
+ { name: "", type: "uint256", internalType: "uint256" }
2723
+ ],
2724
+ stateMutability: "view"
2725
+ },
2726
+ {
2727
+ type: "function",
2728
+ name: "decryptForTxWithPermit",
2729
+ inputs: [
2730
+ { name: "ctHash", type: "uint256", internalType: "uint256" },
2731
+ {
2732
+ name: "permission",
2733
+ type: "tuple",
2734
+ internalType: "struct Permission",
2735
+ components: [
2736
+ { name: "issuer", type: "address", internalType: "address" },
2737
+ { name: "expiration", type: "uint64", internalType: "uint64" },
2738
+ { name: "recipient", type: "address", internalType: "address" },
2739
+ { name: "validatorId", type: "uint256", internalType: "uint256" },
2740
+ { name: "validatorContract", type: "address", internalType: "address" },
2741
+ { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2742
+ { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2743
+ { name: "recipientSignature", type: "bytes", internalType: "bytes" }
2744
+ ]
2745
+ }
2746
+ ],
2747
+ outputs: [
2748
+ { name: "allowed", type: "bool", internalType: "bool" },
2749
+ { name: "error", type: "string", internalType: "string" },
2750
+ { name: "decryptedValue", type: "uint256", internalType: "uint256" }
2751
+ ],
2752
+ stateMutability: "view"
2753
+ },
2754
+ {
2755
+ type: "function",
2756
+ name: "decryptForTxWithoutPermit",
2757
+ inputs: [{ name: "ctHash", type: "uint256", internalType: "uint256" }],
2758
+ outputs: [
2759
+ { name: "allowed", type: "bool", internalType: "bool" },
2760
+ { name: "error", type: "string", internalType: "string" },
2761
+ { name: "decryptedValue", type: "uint256", internalType: "uint256" }
2762
+ ],
2763
+ stateMutability: "view"
2764
+ }
2576
2765
  ];
2577
2766
 
2578
- // core/decrypt/cofheMocksSealOutput.ts
2579
- var MockQueryDecrypterAddress = "0x0000000000000000000000000000000000000200";
2580
- async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSealOutputDelay) {
2581
- if (mocksSealOutputDelay > 0)
2582
- await sleep(mocksSealOutputDelay);
2767
+ // core/decrypt/cofheMocksDecryptForView.ts
2768
+ async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient, mocksDecryptDelay) {
2769
+ if (mocksDecryptDelay > 0)
2770
+ await sleep(mocksDecryptDelay);
2583
2771
  const permission = PermitUtils.getPermission(permit, true);
2584
2772
  const permissionWithBigInts = {
2585
2773
  ...permission,
@@ -2587,19 +2775,19 @@ async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSe
2587
2775
  validatorId: BigInt(permission.validatorId)
2588
2776
  };
2589
2777
  const [allowed, error, result] = await publicClient.readContract({
2590
- address: MockQueryDecrypterAddress,
2591
- abi: MockQueryDecrypterAbi,
2778
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
2779
+ abi: MockThresholdNetworkAbi,
2592
2780
  functionName: "querySealOutput",
2593
2781
  args: [ctHash, BigInt(utype), permissionWithBigInts]
2594
2782
  });
2595
2783
  if (error != "") {
2596
- throw new CofhesdkError({
2784
+ throw new CofheError({
2597
2785
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2598
2786
  message: `mocks querySealOutput call failed: ${error}`
2599
2787
  });
2600
2788
  }
2601
2789
  if (allowed == false) {
2602
- throw new CofhesdkError({
2790
+ throw new CofheError({
2603
2791
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2604
2792
  message: `mocks querySealOutput call failed: ACL Access Denied (NotAllowed)`
2605
2793
  });
@@ -2618,7 +2806,7 @@ function numberArrayToUint8Array(arr) {
2618
2806
  }
2619
2807
  function convertSealedData(sealed) {
2620
2808
  if (!sealed) {
2621
- throw new CofhesdkError({
2809
+ throw new CofheError({
2622
2810
  code: "SEAL_OUTPUT_RETURNED_NULL" /* SealOutputReturnedNull */,
2623
2811
  message: "Sealed data is missing from completed response"
2624
2812
  });
@@ -2645,7 +2833,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2645
2833
  body: JSON.stringify(body)
2646
2834
  });
2647
2835
  } catch (e) {
2648
- throw new CofhesdkError({
2836
+ throw new CofheError({
2649
2837
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2650
2838
  message: `sealOutput request failed`,
2651
2839
  hint: "Ensure the threshold network URL is valid and reachable.",
@@ -2664,7 +2852,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2664
2852
  } catch {
2665
2853
  errorMessage = response.statusText || errorMessage;
2666
2854
  }
2667
- throw new CofhesdkError({
2855
+ throw new CofheError({
2668
2856
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2669
2857
  message: `sealOutput request failed: ${errorMessage}`,
2670
2858
  hint: "Check the threshold network URL and request parameters.",
@@ -2680,7 +2868,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2680
2868
  try {
2681
2869
  submitResponse = await response.json();
2682
2870
  } catch (e) {
2683
- throw new CofhesdkError({
2871
+ throw new CofheError({
2684
2872
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2685
2873
  message: `Failed to parse sealOutput submit response`,
2686
2874
  cause: e instanceof Error ? e : void 0,
@@ -2691,7 +2879,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
2691
2879
  });
2692
2880
  }
2693
2881
  if (!submitResponse.request_id) {
2694
- throw new CofhesdkError({
2882
+ throw new CofheError({
2695
2883
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2696
2884
  message: `sealOutput submit response missing request_id`,
2697
2885
  context: {
@@ -2708,7 +2896,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2708
2896
  let completed = false;
2709
2897
  while (!completed) {
2710
2898
  if (Date.now() - startTime > POLL_TIMEOUT_MS) {
2711
- throw new CofhesdkError({
2899
+ throw new CofheError({
2712
2900
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2713
2901
  message: `sealOutput polling timed out after ${POLL_TIMEOUT_MS}ms`,
2714
2902
  hint: "The request may still be processing. Try again later.",
@@ -2728,7 +2916,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2728
2916
  }
2729
2917
  });
2730
2918
  } catch (e) {
2731
- throw new CofhesdkError({
2919
+ throw new CofheError({
2732
2920
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2733
2921
  message: `sealOutput status poll failed`,
2734
2922
  hint: "Ensure the threshold network URL is valid and reachable.",
@@ -2740,7 +2928,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2740
2928
  });
2741
2929
  }
2742
2930
  if (response.status === 404) {
2743
- throw new CofhesdkError({
2931
+ throw new CofheError({
2744
2932
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2745
2933
  message: `sealOutput request not found: ${requestId}`,
2746
2934
  hint: "The request may have expired or been invalid.",
@@ -2758,7 +2946,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2758
2946
  } catch {
2759
2947
  errorMessage = response.statusText || errorMessage;
2760
2948
  }
2761
- throw new CofhesdkError({
2949
+ throw new CofheError({
2762
2950
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2763
2951
  message: `sealOutput status poll failed: ${errorMessage}`,
2764
2952
  context: {
@@ -2773,7 +2961,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2773
2961
  try {
2774
2962
  statusResponse = await response.json();
2775
2963
  } catch (e) {
2776
- throw new CofhesdkError({
2964
+ throw new CofheError({
2777
2965
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2778
2966
  message: `Failed to parse sealOutput status response`,
2779
2967
  cause: e instanceof Error ? e : void 0,
@@ -2786,7 +2974,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2786
2974
  if (statusResponse.status === "COMPLETED") {
2787
2975
  if (statusResponse.is_succeed === false) {
2788
2976
  const errorMessage = statusResponse.error_message || "Unknown error";
2789
- throw new CofhesdkError({
2977
+ throw new CofheError({
2790
2978
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2791
2979
  message: `sealOutput request failed: ${errorMessage}`,
2792
2980
  context: {
@@ -2797,7 +2985,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2797
2985
  });
2798
2986
  }
2799
2987
  if (!statusResponse.sealed) {
2800
- throw new CofhesdkError({
2988
+ throw new CofheError({
2801
2989
  code: "SEAL_OUTPUT_RETURNED_NULL" /* SealOutputReturnedNull */,
2802
2990
  message: `sealOutput request completed but returned no sealed data`,
2803
2991
  context: {
@@ -2811,7 +2999,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
2811
2999
  }
2812
3000
  await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
2813
3001
  }
2814
- throw new CofhesdkError({
3002
+ throw new CofheError({
2815
3003
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
2816
3004
  message: "Polling loop exited unexpectedly",
2817
3005
  context: {
@@ -2824,9 +3012,99 @@ async function tnSealOutputV2(ctHash, chainId, permission, thresholdNetworkUrl)
2824
3012
  const requestId = await submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission);
2825
3013
  return await pollSealOutputStatus(thresholdNetworkUrl, requestId);
2826
3014
  }
3015
+ async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient, mocksDecryptForTxDelay) {
3016
+ if (mocksDecryptForTxDelay > 0)
3017
+ await sleep(mocksDecryptForTxDelay);
3018
+ if (permit !== null) {
3019
+ let permission = PermitUtils.getPermission(permit, true);
3020
+ const permissionWithBigInts = {
3021
+ ...permission,
3022
+ expiration: BigInt(permission.expiration),
3023
+ validatorId: BigInt(permission.validatorId)
3024
+ };
3025
+ const [allowed2, error2, result2] = await publicClient.readContract({
3026
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
3027
+ abi: MockThresholdNetworkAbi,
3028
+ functionName: "decryptForTxWithPermit",
3029
+ args: [ctHash, permissionWithBigInts]
3030
+ });
3031
+ if (error2 != "") {
3032
+ throw new CofheError({
3033
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3034
+ message: `mocks decryptForTx call failed: ${error2}`
3035
+ });
3036
+ }
3037
+ if (allowed2 == false) {
3038
+ throw new CofheError({
3039
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3040
+ message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
3041
+ });
3042
+ }
3043
+ const chainId2 = await publicClient.getChainId();
3044
+ const ctHashBigInt2 = BigInt(ctHash);
3045
+ const resultBigInt2 = BigInt(result2);
3046
+ const encryptionType2 = Number((ctHashBigInt2 & 0x7fn << 8n) >> 8n);
3047
+ const ctHashBytes322 = viem.pad(viem.toHex(ctHashBigInt2), { size: 32 });
3048
+ const packed2 = viem.encodePacked(
3049
+ ["uint256", "uint32", "uint64", "bytes32"],
3050
+ [resultBigInt2, encryptionType2, BigInt(chainId2), ctHashBytes322]
3051
+ );
3052
+ const messageHash2 = viem.keccak256(packed2);
3053
+ const signatureHex2 = await accounts.sign({
3054
+ hash: messageHash2,
3055
+ privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
3056
+ to: "hex"
3057
+ });
3058
+ const signature2 = signatureHex2.slice(2);
3059
+ return {
3060
+ ctHash,
3061
+ decryptedValue: BigInt(result2),
3062
+ signature: signature2
3063
+ };
3064
+ }
3065
+ const [allowed, error, result] = await publicClient.readContract({
3066
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
3067
+ abi: MockThresholdNetworkAbi,
3068
+ functionName: "decryptForTxWithoutPermit",
3069
+ args: [ctHash]
3070
+ });
3071
+ if (error != "") {
3072
+ throw new CofheError({
3073
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3074
+ message: `mocks decryptForTx call failed: ${error}`
3075
+ });
3076
+ }
3077
+ if (allowed == false) {
3078
+ throw new CofheError({
3079
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3080
+ message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`
3081
+ });
3082
+ }
3083
+ const chainId = await publicClient.getChainId();
3084
+ const ctHashBigInt = BigInt(ctHash);
3085
+ const resultBigInt = BigInt(result);
3086
+ const encryptionType = Number((ctHashBigInt & 0x7fn << 8n) >> 8n);
3087
+ const ctHashBytes32 = viem.pad(viem.toHex(ctHashBigInt), { size: 32 });
3088
+ const packed = viem.encodePacked(
3089
+ ["uint256", "uint32", "uint64", "bytes32"],
3090
+ [resultBigInt, encryptionType, BigInt(chainId), ctHashBytes32]
3091
+ );
3092
+ const messageHash = viem.keccak256(packed);
3093
+ const signatureHex = await accounts.sign({
3094
+ hash: messageHash,
3095
+ privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
3096
+ to: "hex"
3097
+ });
3098
+ const signature = signatureHex.slice(2);
3099
+ return {
3100
+ ctHash,
3101
+ decryptedValue: BigInt(result),
3102
+ signature
3103
+ };
3104
+ }
2827
3105
 
2828
- // core/decrypt/decryptHandleBuilder.ts
2829
- var DecryptHandlesBuilder = class extends BaseBuilder {
3106
+ // core/decrypt/decryptForViewBuilder.ts
3107
+ var DecryptForViewBuilder = class extends BaseBuilder {
2830
3108
  ctHash;
2831
3109
  utype;
2832
3110
  permitHash;
@@ -2852,12 +3130,12 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2852
3130
  *
2853
3131
  * Example:
2854
3132
  * ```typescript
2855
- * const unsealed = await decryptHandle(ctHash, utype)
3133
+ * const unsealed = await client.decryptForView(ctHash, utype)
2856
3134
  * .setChainId(11155111)
2857
- * .decrypt();
3135
+ * .execute();
2858
3136
  * ```
2859
3137
  *
2860
- * @returns The chainable DecryptHandlesBuilder instance.
3138
+ * @returns The chainable DecryptForViewBuilder instance.
2861
3139
  */
2862
3140
  setChainId(chainId) {
2863
3141
  this.chainId = chainId;
@@ -2873,12 +3151,12 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2873
3151
  *
2874
3152
  * Example:
2875
3153
  * ```typescript
2876
- * const unsealed = await decryptHandle(ctHash, utype)
3154
+ * const unsealed = await client.decryptForView(ctHash, utype)
2877
3155
  * .setAccount('0x1234567890123456789012345678901234567890')
2878
- * .decrypt();
3156
+ * .execute();
2879
3157
  * ```
2880
3158
  *
2881
- * @returns The chainable DecryptHandlesBuilder instance.
3159
+ * @returns The chainable DecryptForViewBuilder instance.
2882
3160
  */
2883
3161
  setAccount(account) {
2884
3162
  this.account = account;
@@ -2887,6 +3165,19 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2887
3165
  getAccount() {
2888
3166
  return this.account;
2889
3167
  }
3168
+ withPermit(permitOrPermitHash) {
3169
+ if (typeof permitOrPermitHash === "string") {
3170
+ this.permitHash = permitOrPermitHash;
3171
+ this.permit = void 0;
3172
+ } else if (permitOrPermitHash === void 0) {
3173
+ this.permitHash = void 0;
3174
+ this.permit = void 0;
3175
+ } else {
3176
+ this.permit = permitOrPermitHash;
3177
+ this.permitHash = void 0;
3178
+ }
3179
+ return this;
3180
+ }
2890
3181
  /**
2891
3182
  * @param permitHash - Permit hash to decrypt values from. Used to fetch the correct permit.
2892
3183
  *
@@ -2895,16 +3186,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2895
3186
  *
2896
3187
  * Example:
2897
3188
  * ```typescript
2898
- * const unsealed = await decryptHandle(ctHash, utype)
3189
+ * const unsealed = await client.decryptForView(ctHash, utype)
2899
3190
  * .setPermitHash('0x1234567890123456789012345678901234567890')
2900
- * .decrypt();
3191
+ * .execute();
2901
3192
  * ```
2902
3193
  *
2903
- * @returns The chainable DecryptHandlesBuilder instance.
3194
+ * @returns The chainable DecryptForViewBuilder instance.
2904
3195
  */
3196
+ /** @deprecated Use `withPermit(permitHash)` instead. */
2905
3197
  setPermitHash(permitHash) {
2906
- this.permitHash = permitHash;
2907
- return this;
3198
+ return this.withPermit(permitHash);
2908
3199
  }
2909
3200
  getPermitHash() {
2910
3201
  return this.permitHash;
@@ -2916,16 +3207,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2916
3207
  *
2917
3208
  * Example:
2918
3209
  * ```typescript
2919
- * const unsealed = await decryptHandle(ctHash, utype)
3210
+ * const unsealed = await client.decryptForView(ctHash, utype)
2920
3211
  * .setPermit(permit)
2921
- * .decrypt();
3212
+ * .execute();
2922
3213
  * ```
2923
3214
  *
2924
- * @returns The chainable DecryptHandlesBuilder instance.
3215
+ * @returns The chainable DecryptForViewBuilder instance.
2925
3216
  */
3217
+ /** @deprecated Use `withPermit(permit)` instead. */
2926
3218
  setPermit(permit) {
2927
- this.permit = permit;
2928
- return this;
3219
+ return this.withPermit(permit);
2929
3220
  }
2930
3221
  getPermit() {
2931
3222
  return this.permit;
@@ -2936,7 +3227,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2936
3227
  }
2937
3228
  validateUtypeOrThrow() {
2938
3229
  if (!isValidUtype(this.utype))
2939
- throw new CofhesdkError({
3230
+ throw new CofheError({
2940
3231
  code: "INVALID_UTYPE" /* InvalidUtype */,
2941
3232
  message: `Invalid utype to decrypt to`,
2942
3233
  context: {
@@ -2952,7 +3243,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2952
3243
  if (this.permitHash) {
2953
3244
  const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
2954
3245
  if (!permit2) {
2955
- throw new CofhesdkError({
3246
+ throw new CofheError({
2956
3247
  code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
2957
3248
  message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
2958
3249
  hint: "Ensure the permit exists and is valid.",
@@ -2967,7 +3258,7 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2967
3258
  }
2968
3259
  const permit = await permits.getActivePermit(this.chainId, this.account);
2969
3260
  if (!permit) {
2970
- throw new CofhesdkError({
3261
+ throw new CofheError({
2971
3262
  code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
2972
3263
  message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
2973
3264
  hint: "Ensure a permit exists for this account on this chain.",
@@ -2984,8 +3275,8 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
2984
3275
  */
2985
3276
  async mocksSealOutput(permit) {
2986
3277
  this.assertPublicClient();
2987
- const mocksSealOutputDelay = this.config.mocks.sealOutputDelay;
2988
- return cofheMocksSealOutput(this.ctHash, this.utype, permit, this.publicClient, mocksSealOutputDelay);
3278
+ const mocksDecryptDelay = this.config.mocks.decryptDelay;
3279
+ return cofheMocksDecryptForView(this.ctHash, this.utype, permit, this.publicClient, mocksDecryptDelay);
2989
3280
  }
2990
3281
  /**
2991
3282
  * In the production context, perform a true decryption with the CoFHE coprocessor.
@@ -3010,15 +3301,16 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3010
3301
  *
3011
3302
  * Example:
3012
3303
  * ```typescript
3013
- * const unsealed = await decryptHandle(ctHash, utype)
3304
+ * const unsealed = await client.decryptForView(ctHash, utype)
3014
3305
  * .setChainId(11155111) // optional
3015
3306
  * .setAccount('0x123...890') // optional
3016
- * .decrypt(); // execute
3307
+ * .withPermit() // optional
3308
+ * .execute(); // execute
3017
3309
  * ```
3018
3310
  *
3019
3311
  * @returns The unsealed item.
3020
3312
  */
3021
- async decrypt() {
3313
+ async execute() {
3022
3314
  this.validateUtypeOrThrow();
3023
3315
  const permit = await this.getResolvedPermit();
3024
3316
  PermitUtils.validate(permit);
@@ -3034,6 +3326,394 @@ var DecryptHandlesBuilder = class extends BaseBuilder {
3034
3326
  }
3035
3327
  };
3036
3328
 
3329
+ // core/decrypt/tnDecrypt.ts
3330
+ function normalizeSignature(signature) {
3331
+ if (typeof signature !== "string") {
3332
+ throw new CofheError({
3333
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3334
+ message: "decrypt response missing signature",
3335
+ context: {
3336
+ signature
3337
+ }
3338
+ });
3339
+ }
3340
+ const trimmed = signature.trim();
3341
+ if (trimmed.length === 0) {
3342
+ throw new CofheError({
3343
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3344
+ message: "decrypt response returned empty signature"
3345
+ });
3346
+ }
3347
+ return trimmed.startsWith("0x") ? trimmed.slice(2) : trimmed;
3348
+ }
3349
+ function parseDecryptedBytesToBigInt(decrypted) {
3350
+ if (!Array.isArray(decrypted)) {
3351
+ throw new CofheError({
3352
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3353
+ message: "decrypt response field <decrypted> must be a byte array",
3354
+ context: {
3355
+ decrypted
3356
+ }
3357
+ });
3358
+ }
3359
+ if (decrypted.length === 0) {
3360
+ throw new CofheError({
3361
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3362
+ message: "decrypt response field <decrypted> was an empty byte array",
3363
+ context: {
3364
+ decrypted
3365
+ }
3366
+ });
3367
+ }
3368
+ let hex = "";
3369
+ for (const b of decrypted) {
3370
+ if (typeof b !== "number" || !Number.isInteger(b) || b < 0 || b > 255) {
3371
+ throw new CofheError({
3372
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3373
+ message: "decrypt response field <decrypted> contained a non-byte value",
3374
+ context: {
3375
+ badElement: b,
3376
+ decrypted
3377
+ }
3378
+ });
3379
+ }
3380
+ hex += b.toString(16).padStart(2, "0");
3381
+ }
3382
+ return BigInt(`0x${hex}`);
3383
+ }
3384
+ function assertTnDecryptResponse(value) {
3385
+ if (value == null || typeof value !== "object") {
3386
+ throw new CofheError({
3387
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3388
+ message: "decrypt response must be a JSON object",
3389
+ context: {
3390
+ value
3391
+ }
3392
+ });
3393
+ }
3394
+ const v = value;
3395
+ const decrypted = v.decrypted;
3396
+ const signature = v.signature;
3397
+ const encryptionType = v.encryption_type;
3398
+ const errorMessage = v.error_message;
3399
+ if (!Array.isArray(decrypted)) {
3400
+ throw new CofheError({
3401
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3402
+ message: "decrypt response missing <decrypted> byte array",
3403
+ context: { decryptResponse: value }
3404
+ });
3405
+ }
3406
+ if (typeof signature !== "string") {
3407
+ throw new CofheError({
3408
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3409
+ message: "decrypt response missing <signature> string",
3410
+ context: { decryptResponse: value }
3411
+ });
3412
+ }
3413
+ if (typeof encryptionType !== "number") {
3414
+ throw new CofheError({
3415
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3416
+ message: "decrypt response missing <encryption_type> number",
3417
+ context: { decryptResponse: value }
3418
+ });
3419
+ }
3420
+ if (!(typeof errorMessage === "string" || errorMessage === null)) {
3421
+ throw new CofheError({
3422
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3423
+ message: "decrypt response field <error_message> must be string or null",
3424
+ context: { decryptResponse: value }
3425
+ });
3426
+ }
3427
+ return {
3428
+ decrypted,
3429
+ signature,
3430
+ encryption_type: encryptionType,
3431
+ error_message: errorMessage
3432
+ };
3433
+ }
3434
+ async function tnDecrypt(ctHash, chainId, permission, thresholdNetworkUrl) {
3435
+ const body = {
3436
+ ct_tempkey: ctHash.toString(16).padStart(64, "0"),
3437
+ host_chain_id: chainId
3438
+ };
3439
+ if (permission) {
3440
+ body.permit = permission;
3441
+ }
3442
+ let response;
3443
+ try {
3444
+ response = await fetch(`${thresholdNetworkUrl}/decrypt`, {
3445
+ method: "POST",
3446
+ headers: {
3447
+ "Content-Type": "application/json"
3448
+ },
3449
+ body: JSON.stringify(body)
3450
+ });
3451
+ } catch (e) {
3452
+ throw new CofheError({
3453
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3454
+ message: `decrypt request failed`,
3455
+ hint: "Ensure the threshold network URL is valid and reachable.",
3456
+ cause: e instanceof Error ? e : void 0,
3457
+ context: {
3458
+ thresholdNetworkUrl,
3459
+ body
3460
+ }
3461
+ });
3462
+ }
3463
+ const responseText = await response.text();
3464
+ if (!response.ok) {
3465
+ let errorMessage = response.statusText || `HTTP ${response.status}`;
3466
+ try {
3467
+ const errorBody = JSON.parse(responseText);
3468
+ const maybeMessage = errorBody.error_message || errorBody.message;
3469
+ if (typeof maybeMessage === "string" && maybeMessage.length > 0)
3470
+ errorMessage = maybeMessage;
3471
+ } catch {
3472
+ const trimmed = responseText.trim();
3473
+ if (trimmed.length > 0)
3474
+ errorMessage = trimmed;
3475
+ }
3476
+ throw new CofheError({
3477
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3478
+ message: `decrypt request failed: ${errorMessage}`,
3479
+ hint: "Check the threshold network URL and request parameters.",
3480
+ context: {
3481
+ thresholdNetworkUrl,
3482
+ status: response.status,
3483
+ statusText: response.statusText,
3484
+ body,
3485
+ responseText
3486
+ }
3487
+ });
3488
+ }
3489
+ let rawJson;
3490
+ try {
3491
+ rawJson = JSON.parse(responseText);
3492
+ } catch (e) {
3493
+ throw new CofheError({
3494
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3495
+ message: `Failed to parse decrypt response`,
3496
+ cause: e instanceof Error ? e : void 0,
3497
+ context: {
3498
+ thresholdNetworkUrl,
3499
+ body,
3500
+ responseText
3501
+ }
3502
+ });
3503
+ }
3504
+ const decryptResponse = assertTnDecryptResponse(rawJson);
3505
+ if (decryptResponse.error_message) {
3506
+ throw new CofheError({
3507
+ code: "DECRYPT_FAILED" /* DecryptFailed */,
3508
+ message: `decrypt request failed: ${decryptResponse.error_message}`,
3509
+ context: {
3510
+ thresholdNetworkUrl,
3511
+ body,
3512
+ decryptResponse
3513
+ }
3514
+ });
3515
+ }
3516
+ const decryptedValue = parseDecryptedBytesToBigInt(decryptResponse.decrypted);
3517
+ const signature = normalizeSignature(decryptResponse.signature);
3518
+ return { decryptedValue, signature };
3519
+ }
3520
+
3521
+ // core/decrypt/decryptForTxBuilder.ts
3522
+ var DecryptForTxBuilder = class extends BaseBuilder {
3523
+ ctHash;
3524
+ permitHash;
3525
+ permit;
3526
+ permitSelection = "unset";
3527
+ constructor(params) {
3528
+ super({
3529
+ config: params.config,
3530
+ publicClient: params.publicClient,
3531
+ walletClient: params.walletClient,
3532
+ chainId: params.chainId,
3533
+ account: params.account,
3534
+ requireConnected: params.requireConnected
3535
+ });
3536
+ this.ctHash = params.ctHash;
3537
+ }
3538
+ setChainId(chainId) {
3539
+ this.chainId = chainId;
3540
+ return this;
3541
+ }
3542
+ getChainId() {
3543
+ return this.chainId;
3544
+ }
3545
+ setAccount(account) {
3546
+ this.account = account;
3547
+ return this;
3548
+ }
3549
+ getAccount() {
3550
+ return this.account;
3551
+ }
3552
+ withPermit(permitOrPermitHash) {
3553
+ if (this.permitSelection === "with-permit") {
3554
+ throw new CofheError({
3555
+ code: "INTERNAL_ERROR" /* InternalError */,
3556
+ message: "decryptForTx: withPermit() can only be selected once.",
3557
+ hint: "Choose the permit mode once. If you need a different permit, start a new decryptForTx() builder chain."
3558
+ });
3559
+ }
3560
+ if (this.permitSelection === "without-permit") {
3561
+ throw new CofheError({
3562
+ code: "INTERNAL_ERROR" /* InternalError */,
3563
+ message: "decryptForTx: cannot call withPermit() after withoutPermit() has been selected.",
3564
+ hint: "Choose exactly one permit mode: either call .withPermit(...) or .withoutPermit(), but not both."
3565
+ });
3566
+ }
3567
+ this.permitSelection = "with-permit";
3568
+ if (typeof permitOrPermitHash === "string") {
3569
+ this.permitHash = permitOrPermitHash;
3570
+ this.permit = void 0;
3571
+ } else if (permitOrPermitHash === void 0) {
3572
+ this.permitHash = void 0;
3573
+ this.permit = void 0;
3574
+ } else {
3575
+ this.permit = permitOrPermitHash;
3576
+ this.permitHash = void 0;
3577
+ }
3578
+ return this;
3579
+ }
3580
+ /**
3581
+ * Select "no permit" mode.
3582
+ *
3583
+ * This uses global allowance (no permit required) and sends an empty permission payload to `/decrypt`.
3584
+ */
3585
+ withoutPermit() {
3586
+ if (this.permitSelection === "without-permit") {
3587
+ throw new CofheError({
3588
+ code: "INTERNAL_ERROR" /* InternalError */,
3589
+ message: "decryptForTx: withoutPermit() can only be selected once.",
3590
+ hint: "Choose the permit mode once. If you need a different mode, start a new decryptForTx() builder chain."
3591
+ });
3592
+ }
3593
+ if (this.permitSelection === "with-permit") {
3594
+ throw new CofheError({
3595
+ code: "INTERNAL_ERROR" /* InternalError */,
3596
+ message: "decryptForTx: cannot call withoutPermit() after withPermit() has been selected.",
3597
+ hint: "Choose exactly one permit mode: either call .withPermit(...) or .withoutPermit(), but not both."
3598
+ });
3599
+ }
3600
+ this.permitSelection = "without-permit";
3601
+ this.permitHash = void 0;
3602
+ this.permit = void 0;
3603
+ return this;
3604
+ }
3605
+ getPermit() {
3606
+ return this.permit;
3607
+ }
3608
+ getPermitHash() {
3609
+ return this.permitHash;
3610
+ }
3611
+ async getThresholdNetworkUrl() {
3612
+ this.assertChainId();
3613
+ return getThresholdNetworkUrlOrThrow(this.config, this.chainId);
3614
+ }
3615
+ async getResolvedPermit() {
3616
+ if (this.permitSelection === "unset") {
3617
+ throw new CofheError({
3618
+ code: "INTERNAL_ERROR" /* InternalError */,
3619
+ message: "decryptForTx: missing permit selection; call withPermit(...) or withoutPermit() before execute().",
3620
+ hint: "Call .withPermit() to use the active permit, or .withoutPermit() for global allowance."
3621
+ });
3622
+ }
3623
+ if (this.permitSelection === "without-permit") {
3624
+ return null;
3625
+ }
3626
+ if (this.permit)
3627
+ return this.permit;
3628
+ this.assertChainId();
3629
+ this.assertAccount();
3630
+ if (this.permitHash) {
3631
+ const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
3632
+ if (!permit2) {
3633
+ throw new CofheError({
3634
+ code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
3635
+ message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
3636
+ hint: "Ensure the permit exists and is valid.",
3637
+ context: {
3638
+ chainId: this.chainId,
3639
+ account: this.account,
3640
+ permitHash: this.permitHash
3641
+ }
3642
+ });
3643
+ }
3644
+ return permit2;
3645
+ }
3646
+ const permit = await permits.getActivePermit(this.chainId, this.account);
3647
+ if (!permit) {
3648
+ throw new CofheError({
3649
+ code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
3650
+ message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
3651
+ hint: "Create a permit (e.g. client.permits.createSelf(...)) and/or set it active (client.permits.selectActivePermit(hash)).",
3652
+ context: {
3653
+ chainId: this.chainId,
3654
+ account: this.account
3655
+ }
3656
+ });
3657
+ }
3658
+ return permit;
3659
+ }
3660
+ /**
3661
+ * On hardhat, interact with MockThresholdNetwork contract
3662
+ */
3663
+ async mocksDecryptForTx(permit) {
3664
+ this.assertPublicClient();
3665
+ const delay = this.config.mocks.decryptDelay;
3666
+ const result = await cofheMocksDecryptForTx(this.ctHash, 0, permit, this.publicClient, delay);
3667
+ return result;
3668
+ }
3669
+ /**
3670
+ * In the production context, perform a true decryption with the CoFHE coprocessor.
3671
+ */
3672
+ async productionDecryptForTx(permit) {
3673
+ this.assertChainId();
3674
+ this.assertPublicClient();
3675
+ const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
3676
+ const permission = permit ? PermitUtils.getPermission(permit, true) : null;
3677
+ const { decryptedValue, signature } = await tnDecrypt(this.ctHash, this.chainId, permission, thresholdNetworkUrl);
3678
+ return {
3679
+ ctHash: this.ctHash,
3680
+ decryptedValue,
3681
+ signature
3682
+ };
3683
+ }
3684
+ /**
3685
+ * Final step of the decryptForTx process. MUST BE CALLED LAST IN THE CHAIN.
3686
+ *
3687
+ * You must explicitly choose one permit mode before calling `execute()`:
3688
+ * - `withPermit(permit)` / `withPermit(permitHash)` / `withPermit()` (active permit)
3689
+ * - `withoutPermit()` (global allowance)
3690
+ */
3691
+ async execute() {
3692
+ const permit = await this.getResolvedPermit();
3693
+ if (permit !== null) {
3694
+ PermitUtils.validate(permit);
3695
+ PermitUtils.isValid(permit);
3696
+ const chainId = permit._signedDomain.chainId;
3697
+ if (chainId === hardhat2.id) {
3698
+ return await this.mocksDecryptForTx(permit);
3699
+ } else {
3700
+ return await this.productionDecryptForTx(permit);
3701
+ }
3702
+ } else {
3703
+ if (!this.chainId) {
3704
+ this.assertPublicClient();
3705
+ this.chainId = await getPublicClientChainID(this.publicClient);
3706
+ }
3707
+ this.assertChainId();
3708
+ if (this.chainId === hardhat2.id) {
3709
+ return await this.mocksDecryptForTx(null);
3710
+ } else {
3711
+ return await this.productionDecryptForTx(null);
3712
+ }
3713
+ }
3714
+ }
3715
+ };
3716
+
3037
3717
  // core/client.ts
3038
3718
  var InitialConnectStore = {
3039
3719
  connected: false,
@@ -3044,9 +3724,10 @@ var InitialConnectStore = {
3044
3724
  publicClient: void 0,
3045
3725
  walletClient: void 0
3046
3726
  };
3047
- function createCofhesdkClientBase(opts) {
3727
+ function createCofheClientBase(opts) {
3048
3728
  const keysStorage = createKeysStore(opts.config.fheKeyStorage);
3049
3729
  const connectStore = vanilla.createStore(() => InitialConnectStore);
3730
+ let connectAttemptId = 0;
3050
3731
  const updateConnectState = (partial) => {
3051
3732
  connectStore.setState((state) => ({ ...state, ...partial }));
3052
3733
  };
@@ -3054,7 +3735,7 @@ function createCofhesdkClientBase(opts) {
3054
3735
  const state = connectStore.getState();
3055
3736
  const notConnected = !state.connected || !state.account || !state.chainId || !state.publicClient || !state.walletClient;
3056
3737
  if (notConnected) {
3057
- throw new CofhesdkError({
3738
+ throw new CofheError({
3058
3739
  code: "NOT_CONNECTED" /* NotConnected */,
3059
3740
  message: "Client must be connected, account and chainId must be initialized",
3060
3741
  hint: "Ensure client.connect() has been called and awaited.",
@@ -3072,6 +3753,8 @@ function createCofhesdkClientBase(opts) {
3072
3753
  const state = connectStore.getState();
3073
3754
  if (state.connected && state.publicClient === publicClient && state.walletClient === walletClient)
3074
3755
  return;
3756
+ connectAttemptId += 1;
3757
+ const localAttemptId = connectAttemptId;
3075
3758
  updateConnectState({
3076
3759
  ...InitialConnectStore,
3077
3760
  connecting: true
@@ -3079,6 +3762,8 @@ function createCofhesdkClientBase(opts) {
3079
3762
  try {
3080
3763
  const chainId = await getPublicClientChainID(publicClient);
3081
3764
  const account = await getWalletClientAccount(walletClient);
3765
+ if (localAttemptId !== connectAttemptId)
3766
+ return;
3082
3767
  updateConnectState({
3083
3768
  connected: true,
3084
3769
  connecting: false,
@@ -3089,6 +3774,8 @@ function createCofhesdkClientBase(opts) {
3089
3774
  walletClient
3090
3775
  });
3091
3776
  } catch (e) {
3777
+ if (localAttemptId !== connectAttemptId)
3778
+ return;
3092
3779
  updateConnectState({
3093
3780
  ...InitialConnectStore,
3094
3781
  connectError: e
@@ -3096,6 +3783,10 @@ function createCofhesdkClientBase(opts) {
3096
3783
  throw e;
3097
3784
  }
3098
3785
  }
3786
+ function disconnect() {
3787
+ connectAttemptId += 1;
3788
+ updateConnectState({ ...InitialConnectStore });
3789
+ }
3099
3790
  function encryptInputs(inputs) {
3100
3791
  const state = connectStore.getState();
3101
3792
  return new EncryptInputsBuilder({
@@ -3115,16 +3806,28 @@ function createCofhesdkClientBase(opts) {
3115
3806
  requireConnected: _requireConnected
3116
3807
  });
3117
3808
  }
3118
- function decryptHandle(ctHash, utype) {
3809
+ function decryptForView(ctHash, utype) {
3119
3810
  const state = connectStore.getState();
3120
- return new DecryptHandlesBuilder({
3811
+ return new DecryptForViewBuilder({
3121
3812
  ctHash,
3122
3813
  utype,
3123
- chainId: state.chainId ?? void 0,
3124
- account: state.account ?? void 0,
3814
+ chainId: state.chainId,
3815
+ account: state.account,
3125
3816
  config: opts.config,
3126
- publicClient: state.publicClient ?? void 0,
3127
- walletClient: state.walletClient ?? void 0,
3817
+ publicClient: state.publicClient,
3818
+ walletClient: state.walletClient,
3819
+ requireConnected: _requireConnected
3820
+ });
3821
+ }
3822
+ function decryptForTx(ctHash) {
3823
+ const state = connectStore.getState();
3824
+ return new DecryptForTxBuilder({
3825
+ ctHash,
3826
+ chainId: state.chainId,
3827
+ account: state.account,
3828
+ config: opts.config,
3829
+ publicClient: state.publicClient,
3830
+ walletClient: state.walletClient,
3128
3831
  requireConnected: _requireConnected
3129
3832
  });
3130
3833
  }
@@ -3133,7 +3836,7 @@ function createCofhesdkClientBase(opts) {
3133
3836
  const _chainId = chainId ?? state.chainId;
3134
3837
  const _account = account ?? state.account;
3135
3838
  if (_chainId == null || _account == null) {
3136
- throw new CofhesdkError({
3839
+ throw new CofheError({
3137
3840
  code: "NOT_CONNECTED" /* NotConnected */,
3138
3841
  message: "ChainId or account not available.",
3139
3842
  hint: "Ensure client.connect() has been called, or provide chainId and account explicitly.",
@@ -3200,9 +3903,9 @@ function createCofhesdkClientBase(opts) {
3200
3903
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
3201
3904
  return permits.selectActivePermit(_chainId, _account, hash);
3202
3905
  },
3203
- removePermit: async (hash, chainId, account, force) => {
3906
+ removePermit: async (hash, chainId, account) => {
3204
3907
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
3205
- return permits.removePermit(_chainId, _account, hash, force);
3908
+ return permits.removePermit(_chainId, _account, hash);
3206
3909
  },
3207
3910
  removeActivePermit: async (chainId, account) => {
3208
3911
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
@@ -3218,6 +3921,9 @@ function createCofhesdkClientBase(opts) {
3218
3921
  getSnapshot: connectStore.getState,
3219
3922
  subscribe: connectStore.subscribe,
3220
3923
  // flags (read-only: reflect snapshot)
3924
+ get connection() {
3925
+ return connectStore.getState();
3926
+ },
3221
3927
  get connected() {
3222
3928
  return connectStore.getState().connected;
3223
3929
  },
@@ -3227,8 +3933,14 @@ function createCofhesdkClientBase(opts) {
3227
3933
  // config & platform-specific (read-only)
3228
3934
  config: opts.config,
3229
3935
  connect,
3936
+ disconnect,
3230
3937
  encryptInputs,
3231
- decryptHandle,
3938
+ decryptForView,
3939
+ /**
3940
+ * @deprecated Use `decryptForView` instead. Kept for backward compatibility.
3941
+ */
3942
+ decryptHandle: decryptForView,
3943
+ decryptForTx,
3232
3944
  permits: clientPermits
3233
3945
  // Add SDK-specific methods below that require connection
3234
3946
  // Example:
@@ -3441,15 +4153,15 @@ async function zkProveWithWorker2(fheKeyHex, crsHex, items, metadata) {
3441
4153
  const workerManager2 = getWorkerManager();
3442
4154
  return await workerManager2.submitProof(fheKeyHex, crsHex, serializedItems, metadata);
3443
4155
  }
3444
- function createCofhesdkConfig(config) {
3445
- return createCofhesdkConfigBase({
4156
+ function createCofheConfig(config) {
4157
+ return createCofheConfigBase({
3446
4158
  environment: "web",
3447
4159
  ...config,
3448
4160
  fheKeyStorage: config.fheKeyStorage === null ? null : config.fheKeyStorage ?? createWebStorage()
3449
4161
  });
3450
4162
  }
3451
- function createCofhesdkClient(config) {
3452
- return createCofhesdkClientBase({
4163
+ function createCofheClient(config) {
4164
+ return createCofheClientBase({
3453
4165
  config,
3454
4166
  zkBuilderAndCrsGenerator,
3455
4167
  tfhePublicKeyDeserializer,
@@ -3460,8 +4172,8 @@ function createCofhesdkClient(config) {
3460
4172
  zkProveWorkerFn: areWorkersAvailable() ? zkProveWithWorker2 : void 0
3461
4173
  });
3462
4174
  }
3463
- function createCofhesdkClientWithCustomWorker(config, customZkProveWorkerFn) {
3464
- return createCofhesdkClientBase({
4175
+ function createCofheClientWithCustomWorker(config, customZkProveWorkerFn) {
4176
+ return createCofheClientBase({
3465
4177
  config,
3466
4178
  zkBuilderAndCrsGenerator,
3467
4179
  tfhePublicKeyDeserializer,
@@ -3472,7 +4184,7 @@ function createCofhesdkClientWithCustomWorker(config, customZkProveWorkerFn) {
3472
4184
  }
3473
4185
 
3474
4186
  exports.areWorkersAvailable = areWorkersAvailable;
3475
- exports.createCofhesdkClient = createCofhesdkClient;
3476
- exports.createCofhesdkClientWithCustomWorker = createCofhesdkClientWithCustomWorker;
3477
- exports.createCofhesdkConfig = createCofhesdkConfig;
4187
+ exports.createCofheClient = createCofheClient;
4188
+ exports.createCofheClientWithCustomWorker = createCofheClientWithCustomWorker;
4189
+ exports.createCofheConfig = createCofheConfig;
3478
4190
  exports.terminateWorker = terminateWorker;