@cofhe/sdk 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/chains/defineChain.ts +2 -2
  3. package/chains/types.ts +3 -3
  4. package/core/client.test.ts +111 -0
  5. package/core/client.ts +22 -2
  6. package/core/clientTypes.ts +7 -1
  7. package/core/config.test.ts +8 -0
  8. package/core/config.ts +10 -4
  9. package/core/consts.ts +18 -0
  10. package/core/decrypt/cofheMocksSealOutput.ts +2 -4
  11. package/core/encrypt/cofheMocksZkVerifySign.ts +4 -11
  12. package/core/index.ts +9 -1
  13. package/core/permits.test.ts +5 -6
  14. package/core/permits.ts +5 -4
  15. package/dist/chains.cjs +4 -7
  16. package/dist/chains.d.cts +12 -12
  17. package/dist/chains.d.ts +12 -12
  18. package/dist/chains.js +1 -1
  19. package/dist/{chunk-WGCRJCBR.js → chunk-I5WFEYXX.js} +33 -19
  20. package/dist/{chunk-UGBVZNRT.js → chunk-R3B5TMVX.js} +308 -189
  21. package/dist/{chunk-WEAZ25JO.js → chunk-TBLR7NNE.js} +4 -7
  22. package/dist/{clientTypes-Es7fyi65.d.ts → clientTypes-RqkgkV2i.d.ts} +34 -93
  23. package/dist/{clientTypes-5_1nwtUe.d.cts → clientTypes-e4filDzK.d.cts} +34 -93
  24. package/dist/core.cjs +343 -208
  25. package/dist/core.d.cts +17 -6
  26. package/dist/core.d.ts +17 -6
  27. package/dist/core.js +3 -3
  28. package/dist/node.cjs +337 -208
  29. package/dist/node.d.cts +3 -3
  30. package/dist/node.d.ts +3 -3
  31. package/dist/node.js +3 -3
  32. package/dist/{permit-fUSe6KKq.d.cts → permit-MZ502UBl.d.cts} +30 -33
  33. package/dist/{permit-fUSe6KKq.d.ts → permit-MZ502UBl.d.ts} +30 -33
  34. package/dist/permits.cjs +305 -187
  35. package/dist/permits.d.cts +111 -812
  36. package/dist/permits.d.ts +111 -812
  37. package/dist/permits.js +1 -1
  38. package/dist/types-YiAC4gig.d.cts +33 -0
  39. package/dist/types-YiAC4gig.d.ts +33 -0
  40. package/dist/web.cjs +337 -208
  41. package/dist/web.d.cts +3 -3
  42. package/dist/web.d.ts +3 -3
  43. package/dist/web.js +3 -3
  44. package/package.json +3 -3
  45. package/permits/localstorage.test.ts +9 -13
  46. package/permits/onchain-utils.ts +221 -0
  47. package/permits/permit.test.ts +51 -5
  48. package/permits/permit.ts +28 -74
  49. package/permits/store.test.ts +10 -50
  50. package/permits/store.ts +4 -14
  51. package/permits/test-utils.ts +10 -2
  52. package/permits/types.ts +22 -9
  53. package/permits/utils.ts +0 -4
  54. package/permits/validation.test.ts +29 -32
  55. package/permits/validation.ts +112 -194
  56. package/dist/types-KImPrEIe.d.cts +0 -48
  57. package/dist/types-KImPrEIe.d.ts +0 -48
package/dist/web.cjs CHANGED
@@ -514,8 +514,14 @@ 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_QUERY_DECRYPTER_ADDRESS = "0x0000000000000000000000000000000000005002";
518
522
  var MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = "0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512";
523
+
524
+ // core/encrypt/cofheMocksZkVerifySign.ts
519
525
  function createMockZkVerifierSigner() {
520
526
  return viem.createWalletClient({
521
527
  chain: chains.hardhat,
@@ -581,7 +587,7 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
581
587
  let ctHashes;
582
588
  try {
583
589
  ctHashes = await publicClient.readContract({
584
- address: MocksZkVerifierAddress,
590
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
585
591
  abi: MockZkVerifierAbi,
586
592
  functionName: "zkVerifyCalcCtHashesPacked",
587
593
  args: calcCtHashesArgs
@@ -592,7 +598,7 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
592
598
  message: `mockZkVerifySign calcCtHashes failed while calling zkVerifyCalcCtHashesPacked`,
593
599
  cause: err instanceof Error ? err : void 0,
594
600
  context: {
595
- address: MocksZkVerifierAddress,
601
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
596
602
  items,
597
603
  account,
598
604
  securityZone,
@@ -625,7 +631,7 @@ async function insertCtHashes(items, walletClient) {
625
631
  try {
626
632
  const account = walletClient.account;
627
633
  await walletClient.writeContract({
628
- address: MocksZkVerifierAddress,
634
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
629
635
  abi: MockZkVerifierAbi,
630
636
  functionName: "insertPackedCtHashes",
631
637
  args: insertPackedCtHashesArgs,
@@ -713,21 +719,18 @@ var CofheChainSchema = zod.z.object({
713
719
  /** Network identifier */
714
720
  network: zod.z.string().min(1),
715
721
  /** coFhe service URL */
716
- coFheUrl: zod.z.string().url(),
722
+ coFheUrl: zod.z.url(),
717
723
  /** Verifier service URL */
718
- verifierUrl: zod.z.string().url(),
724
+ verifierUrl: zod.z.url(),
719
725
  /** Threshold network service URL */
720
- thresholdNetworkUrl: zod.z.string().url(),
726
+ thresholdNetworkUrl: zod.z.url(),
721
727
  /** Environment type */
722
728
  environment: EnvironmentSchema
723
729
  });
724
-
725
- // chains/defineChain.ts
726
730
  function defineChain(chainConfig) {
727
731
  const result = CofheChainSchema.safeParse(chainConfig);
728
732
  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(", ")}`);
733
+ throw new Error(`Invalid chain configuration: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
731
734
  }
732
735
  return result.data;
733
736
  }
@@ -754,9 +757,15 @@ var CofhesdkConfigSchema = zod.z.object({
754
757
  defaultPermitExpiration: zod.z.number().optional().default(60 * 60 * 24 * 30),
755
758
  /** Storage method for fhe keys (defaults to indexedDB on web, filesystem on node) */
756
759
  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()))
760
+ getItem: zod.z.custom((val) => typeof val === "function", {
761
+ message: "getItem must be a function"
762
+ }),
763
+ setItem: zod.z.custom((val) => typeof val === "function", {
764
+ message: "setItem must be a function"
765
+ }),
766
+ removeItem: zod.z.custom((val) => typeof val === "function", {
767
+ message: "removeItem must be a function"
768
+ })
760
769
  }).or(zod.z.null()).default(null),
761
770
  /** Whether to use Web Workers for ZK proof generation (web platform only) */
762
771
  useWorkers: zod.z.boolean().optional().default(true),
@@ -772,7 +781,7 @@ var CofhesdkConfigSchema = zod.z.object({
772
781
  function createCofhesdkConfigBase(config) {
773
782
  const result = CofhesdkConfigSchema.safeParse(config);
774
783
  if (!result.success) {
775
- throw new Error(`Invalid cofhesdk configuration: ${result.error.message}`);
784
+ throw new Error(`Invalid cofhesdk configuration: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
776
785
  }
777
786
  return result.data;
778
787
  }
@@ -1582,9 +1591,6 @@ function isBigIntOrNumber(value) {
1582
1591
  }
1583
1592
  }
1584
1593
  }
1585
- function is0xPrefixed(value) {
1586
- return value.startsWith("0x");
1587
- }
1588
1594
 
1589
1595
  // permits/sealing.ts
1590
1596
  var PRIVATE_KEY_LENGTH = 64;
@@ -1672,158 +1678,137 @@ var SerializedSealingPair = zod.z.object({
1672
1678
  privateKey: zod.z.string(),
1673
1679
  publicKey: zod.z.string()
1674
1680
  });
1681
+ var addressSchema = zod.z.string().refine((val) => viem.isAddress(val), {
1682
+ error: "Invalid address"
1683
+ }).transform((val) => viem.getAddress(val));
1684
+ var addressNotZeroSchema = addressSchema.refine((val) => val !== viem.zeroAddress, {
1685
+ error: "Must not be zeroAddress"
1686
+ });
1687
+ var bytesSchema = zod.z.custom(
1688
+ (val) => {
1689
+ return typeof val === "string" && viem.isHex(val);
1690
+ },
1691
+ {
1692
+ message: "Invalid hex value"
1693
+ }
1694
+ );
1695
+ var bytesNotEmptySchema = bytesSchema.refine((val) => val !== "0x", {
1696
+ error: "Must not be empty"
1697
+ });
1675
1698
  var DEFAULT_EXPIRATION_FN = () => Math.round(Date.now() / 1e3) + 7 * 24 * 60 * 60;
1676
1699
  var zPermitWithDefaults = zod.z.object({
1677
1700
  name: zod.z.string().optional().default("Unnamed Permit"),
1678
1701
  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")
1702
+ issuer: addressNotZeroSchema,
1703
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1704
+ recipient: addressSchema.optional().default(viem.zeroAddress),
1705
+ validatorId: zod.z.int().optional().default(0),
1706
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1707
+ issuerSignature: bytesSchema.optional().default("0x"),
1708
+ recipientSignature: bytesSchema.optional().default("0x")
1694
1709
  });
1695
1710
  var zPermitWithSealingPair = zPermitWithDefaults.extend({
1696
1711
  sealingPair: SerializedSealingPair.optional()
1697
1712
  });
1698
- var ValidatorContractRefinement = [
1713
+ var ExternalValidatorRefinement = [
1699
1714
  (data) => data.validatorId !== 0 && data.validatorContract !== viem.zeroAddress || data.validatorId === 0 && data.validatorContract === viem.zeroAddress,
1700
1715
  {
1701
- message: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
1716
+ error: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
1702
1717
  path: ["validatorId", "validatorContract"]
1703
1718
  }
1704
1719
  ];
1720
+ var RecipientRefinement = [
1721
+ (data) => data.issuer !== data.recipient,
1722
+ {
1723
+ error: "Sharing permit :: issuer and recipient must not be the same",
1724
+ path: ["issuer", "recipient"]
1725
+ }
1726
+ ];
1705
1727
  var SelfPermitOptionsValidator = zod.z.object({
1706
1728
  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
- }),
1729
+ issuer: addressNotZeroSchema,
1714
1730
  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);
1731
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1732
+ recipient: addressSchema.optional().default(viem.zeroAddress),
1733
+ validatorId: zod.z.int().optional().default(0),
1734
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1735
+ issuerSignature: bytesSchema.optional().default("0x"),
1736
+ recipientSignature: bytesSchema.optional().default("0x")
1737
+ }).refine(...ExternalValidatorRefinement);
1734
1738
  var SelfPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "self", {
1735
- message: "Self permit :: type must be 'self'"
1739
+ error: "Type must be 'self'"
1736
1740
  }).refine((data) => data.recipient === viem.zeroAddress, {
1737
- message: "Self permit :: recipient must be zeroAddress"
1741
+ error: "Recipient must be zeroAddress"
1738
1742
  }).refine((data) => data.issuerSignature !== "0x", {
1739
- message: "Self permit :: issuerSignature must be populated"
1743
+ error: "IssuerSignature must be populated"
1740
1744
  }).refine((data) => data.recipientSignature === "0x", {
1741
- message: "Self permit :: recipientSignature must be empty"
1742
- }).refine(...ValidatorContractRefinement);
1745
+ error: "RecipientSignature must be empty"
1746
+ }).refine(...ExternalValidatorRefinement);
1743
1747
  var SharingPermitOptionsValidator = zod.z.object({
1744
1748
  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
- }),
1749
+ issuer: addressNotZeroSchema,
1750
+ recipient: addressNotZeroSchema,
1759
1751
  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);
1752
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1753
+ validatorId: zod.z.int().optional().default(0),
1754
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1755
+ issuerSignature: bytesSchema.optional().default("0x"),
1756
+ recipientSignature: bytesSchema.optional().default("0x")
1757
+ }).refine(...RecipientRefinement).refine(...ExternalValidatorRefinement);
1772
1758
  var SharingPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "sharing", {
1773
- message: "Sharing permit :: type must be 'sharing'"
1759
+ error: "Type must be 'sharing'"
1774
1760
  }).refine((data) => data.recipient !== viem.zeroAddress, {
1775
- message: "Sharing permit :: recipient must not be zeroAddress"
1761
+ error: "Recipient must not be zeroAddress"
1776
1762
  }).refine((data) => data.issuerSignature !== "0x", {
1777
- message: "Sharing permit :: issuerSignature must be populated"
1763
+ error: "IssuerSignature must be populated"
1778
1764
  }).refine((data) => data.recipientSignature === "0x", {
1779
- message: "Sharing permit :: recipientSignature must be empty"
1780
- }).refine(...ValidatorContractRefinement);
1765
+ error: "RecipientSignature must be empty"
1766
+ }).refine(...ExternalValidatorRefinement);
1781
1767
  var ImportPermitOptionsValidator = zod.z.object({
1782
1768
  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
- }),
1769
+ issuer: addressNotZeroSchema,
1770
+ recipient: addressNotZeroSchema,
1802
1771
  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);
1772
+ expiration: zod.z.int(),
1773
+ validatorId: zod.z.int().optional().default(0),
1774
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1775
+ issuerSignature: bytesNotEmptySchema,
1776
+ recipientSignature: bytesSchema.optional().default("0x")
1777
+ }).refine(...ExternalValidatorRefinement);
1812
1778
  var ImportPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "recipient", {
1813
- message: "Import permit :: type must be 'recipient'"
1779
+ error: "Type must be 'recipient'"
1814
1780
  }).refine((data) => data.recipient !== viem.zeroAddress, {
1815
- message: "Import permit :: recipient must not be zeroAddress"
1781
+ error: "Recipient must not be zeroAddress"
1816
1782
  }).refine((data) => data.issuerSignature !== "0x", {
1817
- message: "Import permit :: issuerSignature must be populated"
1783
+ error: "IssuerSignature must be populated"
1818
1784
  }).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);
1785
+ error: "RecipientSignature must be populated"
1786
+ }).refine(...ExternalValidatorRefinement);
1787
+ var safeParseAndThrowFormatted = (schema, data, message) => {
1788
+ const result = schema.safeParse(data);
1789
+ if (!result.success) {
1790
+ throw new Error(`${message}: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
1791
+ }
1792
+ return result.data;
1793
+ };
1794
+ var validateSelfPermitOptions = (options) => {
1795
+ return safeParseAndThrowFormatted(SelfPermitOptionsValidator, options, "Invalid self permit options");
1796
+ };
1797
+ var validateSharingPermitOptions = (options) => {
1798
+ return safeParseAndThrowFormatted(SharingPermitOptionsValidator, options, "Invalid sharing permit options");
1799
+ };
1800
+ var validateImportPermitOptions = (options) => {
1801
+ return safeParseAndThrowFormatted(ImportPermitOptionsValidator, options, "Invalid import permit options");
1802
+ };
1803
+ var validateSelfPermit = (permit) => {
1804
+ return safeParseAndThrowFormatted(SelfPermitValidator, permit, "Invalid self permit");
1805
+ };
1806
+ var validateSharingPermit = (permit) => {
1807
+ return safeParseAndThrowFormatted(SharingPermitValidator, permit, "Invalid sharing permit");
1808
+ };
1809
+ var validateImportPermit = (permit) => {
1810
+ return safeParseAndThrowFormatted(ImportPermitValidator, permit, "Invalid import permit");
1811
+ };
1827
1812
  var ValidationUtils = {
1828
1813
  /**
1829
1814
  * Check if permit is expired
@@ -1917,6 +1902,179 @@ var SignatureUtils = {
1917
1902
  throw new Error(`Unknown permit type: ${permitType}`);
1918
1903
  }
1919
1904
  };
1905
+ var getAclAddress = async (publicClient) => {
1906
+ const ACL_IFACE = "function acl() view returns (address)";
1907
+ const aclAbi = viem.parseAbi([ACL_IFACE]);
1908
+ return await publicClient.readContract({
1909
+ address: TASK_MANAGER_ADDRESS,
1910
+ abi: aclAbi,
1911
+ functionName: "acl"
1912
+ });
1913
+ };
1914
+ var getAclEIP712Domain = async (publicClient) => {
1915
+ const aclAddress = await getAclAddress(publicClient);
1916
+ const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
1917
+ const domainAbi = viem.parseAbi([EIP712_DOMAIN_IFACE]);
1918
+ const domain = await publicClient.readContract({
1919
+ address: aclAddress,
1920
+ abi: domainAbi,
1921
+ functionName: "eip712Domain"
1922
+ });
1923
+ const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
1924
+ return {
1925
+ name,
1926
+ version,
1927
+ chainId: Number(chainId),
1928
+ verifyingContract
1929
+ };
1930
+ };
1931
+ var checkPermitValidityOnChain = async (permission, publicClient) => {
1932
+ const aclAddress = await getAclAddress(publicClient);
1933
+ try {
1934
+ await publicClient.simulateContract({
1935
+ address: aclAddress,
1936
+ abi: checkPermitValidityAbi,
1937
+ functionName: "checkPermitValidity",
1938
+ args: [
1939
+ {
1940
+ issuer: permission.issuer,
1941
+ expiration: BigInt(permission.expiration),
1942
+ recipient: permission.recipient,
1943
+ validatorId: BigInt(permission.validatorId),
1944
+ validatorContract: permission.validatorContract,
1945
+ sealingKey: permission.sealingKey,
1946
+ issuerSignature: permission.issuerSignature,
1947
+ recipientSignature: permission.recipientSignature
1948
+ }
1949
+ ]
1950
+ });
1951
+ return true;
1952
+ } catch (err) {
1953
+ if (err instanceof viem.BaseError) {
1954
+ const revertError = err.walk((err2) => err2 instanceof viem.ContractFunctionRevertedError);
1955
+ if (revertError instanceof viem.ContractFunctionRevertedError) {
1956
+ const errorName = revertError.data?.errorName ?? "";
1957
+ throw new Error(errorName);
1958
+ }
1959
+ }
1960
+ const customErrorName = extractCustomErrorFromDetails(err, checkPermitValidityAbi);
1961
+ if (customErrorName) {
1962
+ throw new Error(customErrorName);
1963
+ }
1964
+ const hhDetailsData = extractReturnData(err);
1965
+ if (hhDetailsData != null) {
1966
+ const decoded = viem.decodeErrorResult({
1967
+ abi: checkPermitValidityAbi,
1968
+ data: hhDetailsData
1969
+ });
1970
+ throw new Error(decoded.errorName);
1971
+ }
1972
+ throw err;
1973
+ }
1974
+ };
1975
+ function extractCustomErrorFromDetails(err, abi) {
1976
+ const anyErr = err;
1977
+ const details = anyErr?.details ?? anyErr?.cause?.details;
1978
+ if (typeof details === "string") {
1979
+ const customErrorMatch = details.match(/reverted with custom error '(\w+)\(\)'/);
1980
+ if (customErrorMatch) {
1981
+ const errorName = customErrorMatch[1];
1982
+ const errorExists = abi.some((item) => item.type === "error" && item.name === errorName);
1983
+ if (errorExists) {
1984
+ return errorName;
1985
+ }
1986
+ }
1987
+ }
1988
+ return void 0;
1989
+ }
1990
+ function extractReturnData(err) {
1991
+ const anyErr = err;
1992
+ const s = anyErr?.details ?? anyErr?.cause?.details ?? anyErr?.shortMessage ?? anyErr?.message ?? String(err);
1993
+ return s.match(/return data:\s*(0x[a-fA-F0-9]+)/)?.[1];
1994
+ }
1995
+ var checkPermitValidityAbi = [
1996
+ {
1997
+ type: "function",
1998
+ name: "checkPermitValidity",
1999
+ inputs: [
2000
+ {
2001
+ name: "permission",
2002
+ type: "tuple",
2003
+ internalType: "struct Permission",
2004
+ components: [
2005
+ {
2006
+ name: "issuer",
2007
+ type: "address",
2008
+ internalType: "address"
2009
+ },
2010
+ {
2011
+ name: "expiration",
2012
+ type: "uint64",
2013
+ internalType: "uint64"
2014
+ },
2015
+ {
2016
+ name: "recipient",
2017
+ type: "address",
2018
+ internalType: "address"
2019
+ },
2020
+ {
2021
+ name: "validatorId",
2022
+ type: "uint256",
2023
+ internalType: "uint256"
2024
+ },
2025
+ {
2026
+ name: "validatorContract",
2027
+ type: "address",
2028
+ internalType: "address"
2029
+ },
2030
+ {
2031
+ name: "sealingKey",
2032
+ type: "bytes32",
2033
+ internalType: "bytes32"
2034
+ },
2035
+ {
2036
+ name: "issuerSignature",
2037
+ type: "bytes",
2038
+ internalType: "bytes"
2039
+ },
2040
+ {
2041
+ name: "recipientSignature",
2042
+ type: "bytes",
2043
+ internalType: "bytes"
2044
+ }
2045
+ ]
2046
+ }
2047
+ ],
2048
+ outputs: [
2049
+ {
2050
+ name: "",
2051
+ type: "bool",
2052
+ internalType: "bool"
2053
+ }
2054
+ ],
2055
+ stateMutability: "view"
2056
+ },
2057
+ {
2058
+ type: "error",
2059
+ name: "PermissionInvalid_Disabled",
2060
+ inputs: []
2061
+ },
2062
+ {
2063
+ type: "error",
2064
+ name: "PermissionInvalid_Expired",
2065
+ inputs: []
2066
+ },
2067
+ {
2068
+ type: "error",
2069
+ name: "PermissionInvalid_IssuerSignature",
2070
+ inputs: []
2071
+ },
2072
+ {
2073
+ type: "error",
2074
+ name: "PermissionInvalid_RecipientSignature",
2075
+ inputs: []
2076
+ }
2077
+ ];
1920
2078
 
1921
2079
  // permits/permit.ts
1922
2080
  var PermitUtils = {
@@ -1925,14 +2083,10 @@ var PermitUtils = {
1925
2083
  */
1926
2084
  createSelf: (options) => {
1927
2085
  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
2086
  const sealingPair = GenerateSealingKey();
1934
2087
  const permit = {
1935
- ...validation.data,
2088
+ hash: PermitUtils.getHash(validation),
2089
+ ...validation,
1936
2090
  sealingPair,
1937
2091
  _signedDomain: void 0
1938
2092
  };
@@ -1943,14 +2097,10 @@ var PermitUtils = {
1943
2097
  */
1944
2098
  createSharing: (options) => {
1945
2099
  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
2100
  const sealingPair = GenerateSealingKey();
1952
2101
  const permit = {
1953
- ...validation.data,
2102
+ hash: PermitUtils.getHash(validation),
2103
+ ...validation,
1954
2104
  sealingPair,
1955
2105
  _signedDomain: void 0
1956
2106
  };
@@ -1965,27 +2115,21 @@ var PermitUtils = {
1965
2115
  try {
1966
2116
  parsedOptions = JSON.parse(options);
1967
2117
  } catch (error) {
1968
- throw new Error(`PermitUtils :: importShared :: Failed to parse JSON string: ${error}`);
2118
+ throw new Error(`Failed to parse JSON string: ${error}`);
1969
2119
  }
1970
2120
  } else if (typeof options === "object" && options !== null) {
1971
2121
  parsedOptions = options;
1972
2122
  } else {
1973
- throw new Error(
1974
- "PermitUtils :: importShared :: Invalid input type, expected ImportSharedPermitOptions, object, or string"
1975
- );
2123
+ throw new Error("Invalid input type, expected ImportSharedPermitOptions, object, or string");
1976
2124
  }
1977
2125
  if (parsedOptions.type != null && parsedOptions.type !== "sharing") {
1978
- throw new Error(`PermitUtils :: importShared :: Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
2126
+ throw new Error(`Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
1979
2127
  }
1980
2128
  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
2129
  const sealingPair = GenerateSealingKey();
1987
2130
  const permit = {
1988
- ...validation.data,
2131
+ hash: PermitUtils.getHash(validation),
2132
+ ...validation,
1989
2133
  sealingPair,
1990
2134
  _signedDomain: void 0
1991
2135
  };
@@ -1997,11 +2141,11 @@ var PermitUtils = {
1997
2141
  sign: async (permit, publicClient, walletClient) => {
1998
2142
  if (walletClient == null || walletClient.account == null) {
1999
2143
  throw new Error(
2000
- "PermitUtils :: sign - walletClient undefined, you must pass in a `walletClient` for the connected user to create a permit signature"
2144
+ "Missing walletClient, you must pass in a `walletClient` for the connected user to create a permit signature"
2001
2145
  );
2002
2146
  }
2003
2147
  const primaryType = SignatureUtils.getPrimaryType(permit.type);
2004
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
2148
+ const domain = await getAclEIP712Domain(publicClient);
2005
2149
  const { types, message } = SignatureUtils.getSignatureParams(PermitUtils.getPermission(permit, true), primaryType);
2006
2150
  const signature = await walletClient.signTypedData({
2007
2151
  domain,
@@ -2061,6 +2205,7 @@ var PermitUtils = {
2061
2205
  */
2062
2206
  serialize: (permit) => {
2063
2207
  return {
2208
+ hash: permit.hash,
2064
2209
  name: permit.name,
2065
2210
  type: permit.type,
2066
2211
  issuer: permit.issuer,
@@ -2085,7 +2230,7 @@ var PermitUtils = {
2085
2230
  } else if (permit.type === "recipient") {
2086
2231
  return validateImportPermit(permit);
2087
2232
  } else {
2088
- throw new Error("PermitUtils :: validate :: Invalid permit type");
2233
+ throw new Error("Invalid permit type");
2089
2234
  }
2090
2235
  },
2091
2236
  /**
@@ -2093,12 +2238,7 @@ var PermitUtils = {
2093
2238
  */
2094
2239
  getPermission: (permit, skipValidation = false) => {
2095
2240
  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
- }
2241
+ PermitUtils.validate(permit);
2102
2242
  }
2103
2243
  return {
2104
2244
  issuer: permit.issuer,
@@ -2179,28 +2319,7 @@ var PermitUtils = {
2179
2319
  * Fetch EIP712 domain from the blockchain
2180
2320
  */
2181
2321
  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
- };
2322
+ return getAclEIP712Domain(publicClient);
2204
2323
  },
2205
2324
  /**
2206
2325
  * Check if permit's signed domain matches the provided domain
@@ -2214,8 +2333,15 @@ var PermitUtils = {
2214
2333
  checkSignedDomainValid: async (permit, publicClient) => {
2215
2334
  if (permit._signedDomain == null)
2216
2335
  return false;
2217
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
2336
+ const domain = await getAclEIP712Domain(publicClient);
2218
2337
  return PermitUtils.matchesDomain(permit, domain);
2338
+ },
2339
+ /**
2340
+ * Check if permit passes the on-chain validation
2341
+ */
2342
+ checkValidityOnChain: async (permit, publicClient) => {
2343
+ const permission = PermitUtils.getPermission(permit);
2344
+ return checkPermitValidityOnChain(permission, publicClient);
2219
2345
  }
2220
2346
  };
2221
2347
  var PERMIT_STORE_DEFAULTS = {
@@ -2269,11 +2395,11 @@ var setPermit = (chainId, account, permit) => {
2269
2395
  state.permits[chainId] = {};
2270
2396
  if (state.permits[chainId][account] == null)
2271
2397
  state.permits[chainId][account] = {};
2272
- state.permits[chainId][account][PermitUtils.getHash(permit)] = PermitUtils.serialize(permit);
2398
+ state.permits[chainId][account][permit.hash] = PermitUtils.serialize(permit);
2273
2399
  })
2274
2400
  );
2275
2401
  };
2276
- var removePermit = (chainId, account, hash, force) => {
2402
+ var removePermit = (chainId, account, hash) => {
2277
2403
  clearStaleStore();
2278
2404
  _permitStore.setState(
2279
2405
  immer.produce((state) => {
@@ -2287,15 +2413,7 @@ var removePermit = (chainId, account, hash, force) => {
2287
2413
  if (accountPermits[hash] == null)
2288
2414
  return;
2289
2415
  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
- }
2416
+ state.activePermitHash[chainId][account] = void 0;
2299
2417
  }
2300
2418
  accountPermits[hash] = void 0;
2301
2419
  })
@@ -2346,7 +2464,7 @@ var storeActivePermit = async (permit, publicClient, walletClient) => {
2346
2464
  const chainId = await publicClient.getChainId();
2347
2465
  const account = walletClient.account.address;
2348
2466
  permitStore.setPermit(chainId, account, permit);
2349
- permitStore.setActivePermitHash(chainId, account, PermitUtils.getHash(permit));
2467
+ permitStore.setActivePermitHash(chainId, account, permit.hash);
2350
2468
  };
2351
2469
  var createPermitWithSign = async (options, publicClient, walletClient, permitMethod) => {
2352
2470
  const permit = await permitMethod(options, publicClient, walletClient);
@@ -2404,7 +2522,7 @@ var getOrCreateSharingPermit = async (publicClient, walletClient, options, chain
2404
2522
  }
2405
2523
  return createSharing(options, publicClient, walletClient);
2406
2524
  };
2407
- var removePermit2 = async (chainId, account, hash, force) => permitStore.removePermit(chainId, account, hash, force);
2525
+ var removePermit2 = async (chainId, account, hash) => permitStore.removePermit(chainId, account, hash);
2408
2526
  var removeActivePermit = async (chainId, account) => permitStore.removeActivePermitHash(chainId, account);
2409
2527
  var permits = {
2410
2528
  getSnapshot: permitStore.store.getState,
@@ -2576,7 +2694,6 @@ var MockQueryDecrypterAbi = [
2576
2694
  ];
2577
2695
 
2578
2696
  // core/decrypt/cofheMocksSealOutput.ts
2579
- var MockQueryDecrypterAddress = "0x0000000000000000000000000000000000000200";
2580
2697
  async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSealOutputDelay) {
2581
2698
  if (mocksSealOutputDelay > 0)
2582
2699
  await sleep(mocksSealOutputDelay);
@@ -2587,7 +2704,7 @@ async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSe
2587
2704
  validatorId: BigInt(permission.validatorId)
2588
2705
  };
2589
2706
  const [allowed, error, result] = await publicClient.readContract({
2590
- address: MockQueryDecrypterAddress,
2707
+ address: MOCKS_QUERY_DECRYPTER_ADDRESS,
2591
2708
  abi: MockQueryDecrypterAbi,
2592
2709
  functionName: "querySealOutput",
2593
2710
  args: [ctHash, BigInt(utype), permissionWithBigInts]
@@ -3047,6 +3164,7 @@ var InitialConnectStore = {
3047
3164
  function createCofhesdkClientBase(opts) {
3048
3165
  const keysStorage = createKeysStore(opts.config.fheKeyStorage);
3049
3166
  const connectStore = vanilla.createStore(() => InitialConnectStore);
3167
+ let connectAttemptId = 0;
3050
3168
  const updateConnectState = (partial) => {
3051
3169
  connectStore.setState((state) => ({ ...state, ...partial }));
3052
3170
  };
@@ -3072,6 +3190,8 @@ function createCofhesdkClientBase(opts) {
3072
3190
  const state = connectStore.getState();
3073
3191
  if (state.connected && state.publicClient === publicClient && state.walletClient === walletClient)
3074
3192
  return;
3193
+ connectAttemptId += 1;
3194
+ const localAttemptId = connectAttemptId;
3075
3195
  updateConnectState({
3076
3196
  ...InitialConnectStore,
3077
3197
  connecting: true
@@ -3079,6 +3199,8 @@ function createCofhesdkClientBase(opts) {
3079
3199
  try {
3080
3200
  const chainId = await getPublicClientChainID(publicClient);
3081
3201
  const account = await getWalletClientAccount(walletClient);
3202
+ if (localAttemptId !== connectAttemptId)
3203
+ return;
3082
3204
  updateConnectState({
3083
3205
  connected: true,
3084
3206
  connecting: false,
@@ -3089,6 +3211,8 @@ function createCofhesdkClientBase(opts) {
3089
3211
  walletClient
3090
3212
  });
3091
3213
  } catch (e) {
3214
+ if (localAttemptId !== connectAttemptId)
3215
+ return;
3092
3216
  updateConnectState({
3093
3217
  ...InitialConnectStore,
3094
3218
  connectError: e
@@ -3096,6 +3220,10 @@ function createCofhesdkClientBase(opts) {
3096
3220
  throw e;
3097
3221
  }
3098
3222
  }
3223
+ function disconnect() {
3224
+ connectAttemptId += 1;
3225
+ updateConnectState({ ...InitialConnectStore });
3226
+ }
3099
3227
  function encryptInputs(inputs) {
3100
3228
  const state = connectStore.getState();
3101
3229
  return new EncryptInputsBuilder({
@@ -3200,9 +3328,9 @@ function createCofhesdkClientBase(opts) {
3200
3328
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
3201
3329
  return permits.selectActivePermit(_chainId, _account, hash);
3202
3330
  },
3203
- removePermit: async (hash, chainId, account, force) => {
3331
+ removePermit: async (hash, chainId, account) => {
3204
3332
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
3205
- return permits.removePermit(_chainId, _account, hash, force);
3333
+ return permits.removePermit(_chainId, _account, hash);
3206
3334
  },
3207
3335
  removeActivePermit: async (chainId, account) => {
3208
3336
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
@@ -3227,6 +3355,7 @@ function createCofhesdkClientBase(opts) {
3227
3355
  // config & platform-specific (read-only)
3228
3356
  config: opts.config,
3229
3357
  connect,
3358
+ disconnect,
3230
3359
  encryptInputs,
3231
3360
  decryptHandle,
3232
3361
  permits: clientPermits