@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/node.cjs CHANGED
@@ -475,8 +475,14 @@ var MockZkVerifierAbi = [
475
475
  },
476
476
  { type: "error", name: "InvalidInputs", inputs: [] }
477
477
  ];
478
- var MocksZkVerifierAddress = "0x0000000000000000000000000000000000000100";
478
+
479
+ // core/consts.ts
480
+ var TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
481
+ var MOCKS_ZK_VERIFIER_ADDRESS = "0x0000000000000000000000000000000000005001";
482
+ var MOCKS_QUERY_DECRYPTER_ADDRESS = "0x0000000000000000000000000000000000005002";
479
483
  var MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = "0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512";
484
+
485
+ // core/encrypt/cofheMocksZkVerifySign.ts
480
486
  function createMockZkVerifierSigner() {
481
487
  return viem.createWalletClient({
482
488
  chain: chains.hardhat,
@@ -542,7 +548,7 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
542
548
  let ctHashes;
543
549
  try {
544
550
  ctHashes = await publicClient.readContract({
545
- address: MocksZkVerifierAddress,
551
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
546
552
  abi: MockZkVerifierAbi,
547
553
  functionName: "zkVerifyCalcCtHashesPacked",
548
554
  args: calcCtHashesArgs
@@ -553,7 +559,7 @@ async function calcCtHashes(items, account, securityZone, publicClient) {
553
559
  message: `mockZkVerifySign calcCtHashes failed while calling zkVerifyCalcCtHashesPacked`,
554
560
  cause: err instanceof Error ? err : void 0,
555
561
  context: {
556
- address: MocksZkVerifierAddress,
562
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
557
563
  items,
558
564
  account,
559
565
  securityZone,
@@ -586,7 +592,7 @@ async function insertCtHashes(items, walletClient) {
586
592
  try {
587
593
  const account = walletClient.account;
588
594
  await walletClient.writeContract({
589
- address: MocksZkVerifierAddress,
595
+ address: MOCKS_ZK_VERIFIER_ADDRESS,
590
596
  abi: MockZkVerifierAbi,
591
597
  functionName: "insertPackedCtHashes",
592
598
  args: insertPackedCtHashesArgs,
@@ -674,21 +680,18 @@ var CofheChainSchema = zod.z.object({
674
680
  /** Network identifier */
675
681
  network: zod.z.string().min(1),
676
682
  /** coFhe service URL */
677
- coFheUrl: zod.z.string().url(),
683
+ coFheUrl: zod.z.url(),
678
684
  /** Verifier service URL */
679
- verifierUrl: zod.z.string().url(),
685
+ verifierUrl: zod.z.url(),
680
686
  /** Threshold network service URL */
681
- thresholdNetworkUrl: zod.z.string().url(),
687
+ thresholdNetworkUrl: zod.z.url(),
682
688
  /** Environment type */
683
689
  environment: EnvironmentSchema
684
690
  });
685
-
686
- // chains/defineChain.ts
687
691
  function defineChain(chainConfig) {
688
692
  const result = CofheChainSchema.safeParse(chainConfig);
689
693
  if (!result.success) {
690
- const errorMessages = result.error.errors.map((err) => `${err.path.join(".")}: ${err.message}`);
691
- throw new Error(`Invalid chain configuration: ${errorMessages.join(", ")}`);
694
+ throw new Error(`Invalid chain configuration: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
692
695
  }
693
696
  return result.data;
694
697
  }
@@ -715,9 +718,15 @@ var CofhesdkConfigSchema = zod.z.object({
715
718
  defaultPermitExpiration: zod.z.number().optional().default(60 * 60 * 24 * 30),
716
719
  /** Storage method for fhe keys (defaults to indexedDB on web, filesystem on node) */
717
720
  fheKeyStorage: zod.z.object({
718
- getItem: zod.z.function().args(zod.z.string()).returns(zod.z.promise(zod.z.any())),
719
- setItem: zod.z.function().args(zod.z.string(), zod.z.any()).returns(zod.z.promise(zod.z.void())),
720
- removeItem: zod.z.function().args(zod.z.string()).returns(zod.z.promise(zod.z.void()))
721
+ getItem: zod.z.custom((val) => typeof val === "function", {
722
+ message: "getItem must be a function"
723
+ }),
724
+ setItem: zod.z.custom((val) => typeof val === "function", {
725
+ message: "setItem must be a function"
726
+ }),
727
+ removeItem: zod.z.custom((val) => typeof val === "function", {
728
+ message: "removeItem must be a function"
729
+ })
721
730
  }).or(zod.z.null()).default(null),
722
731
  /** Whether to use Web Workers for ZK proof generation (web platform only) */
723
732
  useWorkers: zod.z.boolean().optional().default(true),
@@ -733,7 +742,7 @@ var CofhesdkConfigSchema = zod.z.object({
733
742
  function createCofhesdkConfigBase(config) {
734
743
  const result = CofhesdkConfigSchema.safeParse(config);
735
744
  if (!result.success) {
736
- throw new Error(`Invalid cofhesdk configuration: ${result.error.message}`);
745
+ throw new Error(`Invalid cofhesdk configuration: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
737
746
  }
738
747
  return result.data;
739
748
  }
@@ -1543,9 +1552,6 @@ function isBigIntOrNumber(value) {
1543
1552
  }
1544
1553
  }
1545
1554
  }
1546
- function is0xPrefixed(value) {
1547
- return value.startsWith("0x");
1548
- }
1549
1555
 
1550
1556
  // permits/sealing.ts
1551
1557
  var PRIVATE_KEY_LENGTH = 64;
@@ -1633,158 +1639,137 @@ var SerializedSealingPair = zod.z.object({
1633
1639
  privateKey: zod.z.string(),
1634
1640
  publicKey: zod.z.string()
1635
1641
  });
1642
+ var addressSchema = zod.z.string().refine((val) => viem.isAddress(val), {
1643
+ error: "Invalid address"
1644
+ }).transform((val) => viem.getAddress(val));
1645
+ var addressNotZeroSchema = addressSchema.refine((val) => val !== viem.zeroAddress, {
1646
+ error: "Must not be zeroAddress"
1647
+ });
1648
+ var bytesSchema = zod.z.custom(
1649
+ (val) => {
1650
+ return typeof val === "string" && viem.isHex(val);
1651
+ },
1652
+ {
1653
+ message: "Invalid hex value"
1654
+ }
1655
+ );
1656
+ var bytesNotEmptySchema = bytesSchema.refine((val) => val !== "0x", {
1657
+ error: "Must not be empty"
1658
+ });
1636
1659
  var DEFAULT_EXPIRATION_FN = () => Math.round(Date.now() / 1e3) + 7 * 24 * 60 * 60;
1637
1660
  var zPermitWithDefaults = zod.z.object({
1638
1661
  name: zod.z.string().optional().default("Unnamed Permit"),
1639
1662
  type: zod.z.enum(["self", "sharing", "recipient"]),
1640
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1641
- message: "Permit issuer :: invalid address"
1642
- }).refine((val) => val !== viem.zeroAddress, {
1643
- message: "Permit issuer :: must not be zeroAddress"
1644
- }),
1645
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1646
- recipient: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1647
- message: "Permit recipient :: invalid address"
1648
- }),
1649
- validatorId: zod.z.number().optional().default(0),
1650
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1651
- message: "Permit validatorContract :: invalid address"
1652
- }),
1653
- issuerSignature: zod.z.string().optional().default("0x"),
1654
- recipientSignature: zod.z.string().optional().default("0x")
1663
+ issuer: addressNotZeroSchema,
1664
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1665
+ recipient: addressSchema.optional().default(viem.zeroAddress),
1666
+ validatorId: zod.z.int().optional().default(0),
1667
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1668
+ issuerSignature: bytesSchema.optional().default("0x"),
1669
+ recipientSignature: bytesSchema.optional().default("0x")
1655
1670
  });
1656
1671
  var zPermitWithSealingPair = zPermitWithDefaults.extend({
1657
1672
  sealingPair: SerializedSealingPair.optional()
1658
1673
  });
1659
- var ValidatorContractRefinement = [
1674
+ var ExternalValidatorRefinement = [
1660
1675
  (data) => data.validatorId !== 0 && data.validatorContract !== viem.zeroAddress || data.validatorId === 0 && data.validatorContract === viem.zeroAddress,
1661
1676
  {
1662
- message: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
1677
+ error: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
1663
1678
  path: ["validatorId", "validatorContract"]
1664
1679
  }
1665
1680
  ];
1681
+ var RecipientRefinement = [
1682
+ (data) => data.issuer !== data.recipient,
1683
+ {
1684
+ error: "Sharing permit :: issuer and recipient must not be the same",
1685
+ path: ["issuer", "recipient"]
1686
+ }
1687
+ ];
1666
1688
  var SelfPermitOptionsValidator = zod.z.object({
1667
1689
  type: zod.z.literal("self").optional().default("self"),
1668
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1669
- message: "Self permit issuer :: invalid address"
1670
- }).refine((val) => is0xPrefixed(val), {
1671
- message: "Self permit issuer :: must be 0x prefixed"
1672
- }).refine((val) => val !== viem.zeroAddress, {
1673
- message: "Self permit issuer :: must not be zeroAddress"
1674
- }),
1690
+ issuer: addressNotZeroSchema,
1675
1691
  name: zod.z.string().optional().default("Unnamed Permit"),
1676
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1677
- recipient: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1678
- message: "Self permit recipient :: invalid address"
1679
- }).refine((val) => is0xPrefixed(val), {
1680
- message: "Self permit recipient :: must be 0x prefixed"
1681
- }).refine((val) => val === viem.zeroAddress, {
1682
- message: "Self permit recipient :: must be zeroAddress"
1683
- }),
1684
- validatorId: zod.z.number().optional().default(0),
1685
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1686
- message: "Self permit validatorContract :: invalid address"
1687
- }),
1688
- issuerSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1689
- message: "Self permit issuerSignature :: must be 0x prefixed"
1690
- }),
1691
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1692
- message: "Self permit recipientSignature :: must be 0x prefixed"
1693
- })
1694
- }).refine(...ValidatorContractRefinement);
1692
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1693
+ recipient: addressSchema.optional().default(viem.zeroAddress),
1694
+ validatorId: zod.z.int().optional().default(0),
1695
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1696
+ issuerSignature: bytesSchema.optional().default("0x"),
1697
+ recipientSignature: bytesSchema.optional().default("0x")
1698
+ }).refine(...ExternalValidatorRefinement);
1695
1699
  var SelfPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "self", {
1696
- message: "Self permit :: type must be 'self'"
1700
+ error: "Type must be 'self'"
1697
1701
  }).refine((data) => data.recipient === viem.zeroAddress, {
1698
- message: "Self permit :: recipient must be zeroAddress"
1702
+ error: "Recipient must be zeroAddress"
1699
1703
  }).refine((data) => data.issuerSignature !== "0x", {
1700
- message: "Self permit :: issuerSignature must be populated"
1704
+ error: "IssuerSignature must be populated"
1701
1705
  }).refine((data) => data.recipientSignature === "0x", {
1702
- message: "Self permit :: recipientSignature must be empty"
1703
- }).refine(...ValidatorContractRefinement);
1706
+ error: "RecipientSignature must be empty"
1707
+ }).refine(...ExternalValidatorRefinement);
1704
1708
  var SharingPermitOptionsValidator = zod.z.object({
1705
1709
  type: zod.z.literal("sharing").optional().default("sharing"),
1706
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1707
- message: "Sharing permit issuer :: invalid address"
1708
- }).refine((val) => is0xPrefixed(val), {
1709
- message: "Sharing permit issuer :: must be 0x prefixed"
1710
- }).refine((val) => val !== viem.zeroAddress, {
1711
- message: "Sharing permit issuer :: must not be zeroAddress"
1712
- }),
1713
- recipient: zod.z.string().refine((val) => viem.isAddress(val), {
1714
- message: "Sharing permit recipient :: invalid address"
1715
- }).refine((val) => is0xPrefixed(val), {
1716
- message: "Sharing permit recipient :: must be 0x prefixed"
1717
- }).refine((val) => val !== viem.zeroAddress, {
1718
- message: "Sharing permit recipient :: must not be zeroAddress"
1719
- }),
1710
+ issuer: addressNotZeroSchema,
1711
+ recipient: addressNotZeroSchema,
1720
1712
  name: zod.z.string().optional().default("Unnamed Permit"),
1721
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1722
- validatorId: zod.z.number().optional().default(0),
1723
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1724
- message: "Sharing permit validatorContract :: invalid address"
1725
- }),
1726
- issuerSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1727
- message: "Sharing permit issuerSignature :: must be 0x prefixed"
1728
- }),
1729
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1730
- message: "Sharing permit recipientSignature :: must be 0x prefixed"
1731
- })
1732
- }).refine(...ValidatorContractRefinement);
1713
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1714
+ validatorId: zod.z.int().optional().default(0),
1715
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1716
+ issuerSignature: bytesSchema.optional().default("0x"),
1717
+ recipientSignature: bytesSchema.optional().default("0x")
1718
+ }).refine(...RecipientRefinement).refine(...ExternalValidatorRefinement);
1733
1719
  var SharingPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "sharing", {
1734
- message: "Sharing permit :: type must be 'sharing'"
1720
+ error: "Type must be 'sharing'"
1735
1721
  }).refine((data) => data.recipient !== viem.zeroAddress, {
1736
- message: "Sharing permit :: recipient must not be zeroAddress"
1722
+ error: "Recipient must not be zeroAddress"
1737
1723
  }).refine((data) => data.issuerSignature !== "0x", {
1738
- message: "Sharing permit :: issuerSignature must be populated"
1724
+ error: "IssuerSignature must be populated"
1739
1725
  }).refine((data) => data.recipientSignature === "0x", {
1740
- message: "Sharing permit :: recipientSignature must be empty"
1741
- }).refine(...ValidatorContractRefinement);
1726
+ error: "RecipientSignature must be empty"
1727
+ }).refine(...ExternalValidatorRefinement);
1742
1728
  var ImportPermitOptionsValidator = zod.z.object({
1743
1729
  type: zod.z.literal("recipient").optional().default("recipient"),
1744
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
1745
- message: "Import permit issuer :: invalid address"
1746
- }).refine((val) => is0xPrefixed(val), {
1747
- message: "Import permit issuer :: must be 0x prefixed"
1748
- }).refine((val) => val !== viem.zeroAddress, {
1749
- message: "Import permit issuer :: must not be zeroAddress"
1750
- }),
1751
- recipient: zod.z.string().refine((val) => viem.isAddress(val), {
1752
- message: "Import permit recipient :: invalid address"
1753
- }).refine((val) => is0xPrefixed(val), {
1754
- message: "Import permit recipient :: must be 0x prefixed"
1755
- }).refine((val) => val !== viem.zeroAddress, {
1756
- message: "Import permit recipient :: must not be zeroAddress"
1757
- }),
1758
- issuerSignature: zod.z.string().refine((val) => is0xPrefixed(val), {
1759
- message: "Import permit issuerSignature :: must be 0x prefixed"
1760
- }).refine((val) => val !== "0x", {
1761
- message: "Import permit :: issuerSignature must be provided"
1762
- }),
1730
+ issuer: addressNotZeroSchema,
1731
+ recipient: addressNotZeroSchema,
1763
1732
  name: zod.z.string().optional().default("Unnamed Permit"),
1764
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
1765
- validatorId: zod.z.number().optional().default(0),
1766
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
1767
- message: "Import permit validatorContract :: invalid address"
1768
- }),
1769
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
1770
- message: "Import permit recipientSignature :: must be 0x prefixed"
1771
- })
1772
- }).refine(...ValidatorContractRefinement);
1733
+ expiration: zod.z.int(),
1734
+ validatorId: zod.z.int().optional().default(0),
1735
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
1736
+ issuerSignature: bytesNotEmptySchema,
1737
+ recipientSignature: bytesSchema.optional().default("0x")
1738
+ }).refine(...ExternalValidatorRefinement);
1773
1739
  var ImportPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "recipient", {
1774
- message: "Import permit :: type must be 'recipient'"
1740
+ error: "Type must be 'recipient'"
1775
1741
  }).refine((data) => data.recipient !== viem.zeroAddress, {
1776
- message: "Import permit :: recipient must not be zeroAddress"
1742
+ error: "Recipient must not be zeroAddress"
1777
1743
  }).refine((data) => data.issuerSignature !== "0x", {
1778
- message: "Import permit :: issuerSignature must be populated"
1744
+ error: "IssuerSignature must be populated"
1779
1745
  }).refine((data) => data.recipientSignature !== "0x", {
1780
- message: "Import permit :: recipientSignature must be populated"
1781
- }).refine(...ValidatorContractRefinement);
1782
- var validateSelfPermitOptions = (options) => SelfPermitOptionsValidator.safeParse(options);
1783
- var validateSharingPermitOptions = (options) => SharingPermitOptionsValidator.safeParse(options);
1784
- var validateImportPermitOptions = (options) => ImportPermitOptionsValidator.safeParse(options);
1785
- var validateSelfPermit = (permit) => SelfPermitValidator.safeParse(permit);
1786
- var validateSharingPermit = (permit) => SharingPermitValidator.safeParse(permit);
1787
- var validateImportPermit = (permit) => ImportPermitValidator.safeParse(permit);
1746
+ error: "RecipientSignature must be populated"
1747
+ }).refine(...ExternalValidatorRefinement);
1748
+ var safeParseAndThrowFormatted = (schema, data, message) => {
1749
+ const result = schema.safeParse(data);
1750
+ if (!result.success) {
1751
+ throw new Error(`${message}: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
1752
+ }
1753
+ return result.data;
1754
+ };
1755
+ var validateSelfPermitOptions = (options) => {
1756
+ return safeParseAndThrowFormatted(SelfPermitOptionsValidator, options, "Invalid self permit options");
1757
+ };
1758
+ var validateSharingPermitOptions = (options) => {
1759
+ return safeParseAndThrowFormatted(SharingPermitOptionsValidator, options, "Invalid sharing permit options");
1760
+ };
1761
+ var validateImportPermitOptions = (options) => {
1762
+ return safeParseAndThrowFormatted(ImportPermitOptionsValidator, options, "Invalid import permit options");
1763
+ };
1764
+ var validateSelfPermit = (permit) => {
1765
+ return safeParseAndThrowFormatted(SelfPermitValidator, permit, "Invalid self permit");
1766
+ };
1767
+ var validateSharingPermit = (permit) => {
1768
+ return safeParseAndThrowFormatted(SharingPermitValidator, permit, "Invalid sharing permit");
1769
+ };
1770
+ var validateImportPermit = (permit) => {
1771
+ return safeParseAndThrowFormatted(ImportPermitValidator, permit, "Invalid import permit");
1772
+ };
1788
1773
  var ValidationUtils = {
1789
1774
  /**
1790
1775
  * Check if permit is expired
@@ -1878,6 +1863,179 @@ var SignatureUtils = {
1878
1863
  throw new Error(`Unknown permit type: ${permitType}`);
1879
1864
  }
1880
1865
  };
1866
+ var getAclAddress = async (publicClient) => {
1867
+ const ACL_IFACE = "function acl() view returns (address)";
1868
+ const aclAbi = viem.parseAbi([ACL_IFACE]);
1869
+ return await publicClient.readContract({
1870
+ address: TASK_MANAGER_ADDRESS,
1871
+ abi: aclAbi,
1872
+ functionName: "acl"
1873
+ });
1874
+ };
1875
+ var getAclEIP712Domain = async (publicClient) => {
1876
+ const aclAddress = await getAclAddress(publicClient);
1877
+ const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
1878
+ const domainAbi = viem.parseAbi([EIP712_DOMAIN_IFACE]);
1879
+ const domain = await publicClient.readContract({
1880
+ address: aclAddress,
1881
+ abi: domainAbi,
1882
+ functionName: "eip712Domain"
1883
+ });
1884
+ const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
1885
+ return {
1886
+ name,
1887
+ version,
1888
+ chainId: Number(chainId),
1889
+ verifyingContract
1890
+ };
1891
+ };
1892
+ var checkPermitValidityOnChain = async (permission, publicClient) => {
1893
+ const aclAddress = await getAclAddress(publicClient);
1894
+ try {
1895
+ await publicClient.simulateContract({
1896
+ address: aclAddress,
1897
+ abi: checkPermitValidityAbi,
1898
+ functionName: "checkPermitValidity",
1899
+ args: [
1900
+ {
1901
+ issuer: permission.issuer,
1902
+ expiration: BigInt(permission.expiration),
1903
+ recipient: permission.recipient,
1904
+ validatorId: BigInt(permission.validatorId),
1905
+ validatorContract: permission.validatorContract,
1906
+ sealingKey: permission.sealingKey,
1907
+ issuerSignature: permission.issuerSignature,
1908
+ recipientSignature: permission.recipientSignature
1909
+ }
1910
+ ]
1911
+ });
1912
+ return true;
1913
+ } catch (err) {
1914
+ if (err instanceof viem.BaseError) {
1915
+ const revertError = err.walk((err2) => err2 instanceof viem.ContractFunctionRevertedError);
1916
+ if (revertError instanceof viem.ContractFunctionRevertedError) {
1917
+ const errorName = revertError.data?.errorName ?? "";
1918
+ throw new Error(errorName);
1919
+ }
1920
+ }
1921
+ const customErrorName = extractCustomErrorFromDetails(err, checkPermitValidityAbi);
1922
+ if (customErrorName) {
1923
+ throw new Error(customErrorName);
1924
+ }
1925
+ const hhDetailsData = extractReturnData(err);
1926
+ if (hhDetailsData != null) {
1927
+ const decoded = viem.decodeErrorResult({
1928
+ abi: checkPermitValidityAbi,
1929
+ data: hhDetailsData
1930
+ });
1931
+ throw new Error(decoded.errorName);
1932
+ }
1933
+ throw err;
1934
+ }
1935
+ };
1936
+ function extractCustomErrorFromDetails(err, abi) {
1937
+ const anyErr = err;
1938
+ const details = anyErr?.details ?? anyErr?.cause?.details;
1939
+ if (typeof details === "string") {
1940
+ const customErrorMatch = details.match(/reverted with custom error '(\w+)\(\)'/);
1941
+ if (customErrorMatch) {
1942
+ const errorName = customErrorMatch[1];
1943
+ const errorExists = abi.some((item) => item.type === "error" && item.name === errorName);
1944
+ if (errorExists) {
1945
+ return errorName;
1946
+ }
1947
+ }
1948
+ }
1949
+ return void 0;
1950
+ }
1951
+ function extractReturnData(err) {
1952
+ const anyErr = err;
1953
+ const s = anyErr?.details ?? anyErr?.cause?.details ?? anyErr?.shortMessage ?? anyErr?.message ?? String(err);
1954
+ return s.match(/return data:\s*(0x[a-fA-F0-9]+)/)?.[1];
1955
+ }
1956
+ var checkPermitValidityAbi = [
1957
+ {
1958
+ type: "function",
1959
+ name: "checkPermitValidity",
1960
+ inputs: [
1961
+ {
1962
+ name: "permission",
1963
+ type: "tuple",
1964
+ internalType: "struct Permission",
1965
+ components: [
1966
+ {
1967
+ name: "issuer",
1968
+ type: "address",
1969
+ internalType: "address"
1970
+ },
1971
+ {
1972
+ name: "expiration",
1973
+ type: "uint64",
1974
+ internalType: "uint64"
1975
+ },
1976
+ {
1977
+ name: "recipient",
1978
+ type: "address",
1979
+ internalType: "address"
1980
+ },
1981
+ {
1982
+ name: "validatorId",
1983
+ type: "uint256",
1984
+ internalType: "uint256"
1985
+ },
1986
+ {
1987
+ name: "validatorContract",
1988
+ type: "address",
1989
+ internalType: "address"
1990
+ },
1991
+ {
1992
+ name: "sealingKey",
1993
+ type: "bytes32",
1994
+ internalType: "bytes32"
1995
+ },
1996
+ {
1997
+ name: "issuerSignature",
1998
+ type: "bytes",
1999
+ internalType: "bytes"
2000
+ },
2001
+ {
2002
+ name: "recipientSignature",
2003
+ type: "bytes",
2004
+ internalType: "bytes"
2005
+ }
2006
+ ]
2007
+ }
2008
+ ],
2009
+ outputs: [
2010
+ {
2011
+ name: "",
2012
+ type: "bool",
2013
+ internalType: "bool"
2014
+ }
2015
+ ],
2016
+ stateMutability: "view"
2017
+ },
2018
+ {
2019
+ type: "error",
2020
+ name: "PermissionInvalid_Disabled",
2021
+ inputs: []
2022
+ },
2023
+ {
2024
+ type: "error",
2025
+ name: "PermissionInvalid_Expired",
2026
+ inputs: []
2027
+ },
2028
+ {
2029
+ type: "error",
2030
+ name: "PermissionInvalid_IssuerSignature",
2031
+ inputs: []
2032
+ },
2033
+ {
2034
+ type: "error",
2035
+ name: "PermissionInvalid_RecipientSignature",
2036
+ inputs: []
2037
+ }
2038
+ ];
1881
2039
 
1882
2040
  // permits/permit.ts
1883
2041
  var PermitUtils = {
@@ -1886,14 +2044,10 @@ var PermitUtils = {
1886
2044
  */
1887
2045
  createSelf: (options) => {
1888
2046
  const validation = validateSelfPermitOptions(options);
1889
- if (!validation.success) {
1890
- throw new Error(
1891
- "PermitUtils :: createSelf :: Parsing SelfPermitOptions failed " + JSON.stringify(validation.error, null, 2)
1892
- );
1893
- }
1894
2047
  const sealingPair = GenerateSealingKey();
1895
2048
  const permit = {
1896
- ...validation.data,
2049
+ hash: PermitUtils.getHash(validation),
2050
+ ...validation,
1897
2051
  sealingPair,
1898
2052
  _signedDomain: void 0
1899
2053
  };
@@ -1904,14 +2058,10 @@ var PermitUtils = {
1904
2058
  */
1905
2059
  createSharing: (options) => {
1906
2060
  const validation = validateSharingPermitOptions(options);
1907
- if (!validation.success) {
1908
- throw new Error(
1909
- "PermitUtils :: createSharing :: Parsing SharingPermitOptions failed " + JSON.stringify(validation.error, null, 2)
1910
- );
1911
- }
1912
2061
  const sealingPair = GenerateSealingKey();
1913
2062
  const permit = {
1914
- ...validation.data,
2063
+ hash: PermitUtils.getHash(validation),
2064
+ ...validation,
1915
2065
  sealingPair,
1916
2066
  _signedDomain: void 0
1917
2067
  };
@@ -1926,27 +2076,21 @@ var PermitUtils = {
1926
2076
  try {
1927
2077
  parsedOptions = JSON.parse(options);
1928
2078
  } catch (error) {
1929
- throw new Error(`PermitUtils :: importShared :: Failed to parse JSON string: ${error}`);
2079
+ throw new Error(`Failed to parse JSON string: ${error}`);
1930
2080
  }
1931
2081
  } else if (typeof options === "object" && options !== null) {
1932
2082
  parsedOptions = options;
1933
2083
  } else {
1934
- throw new Error(
1935
- "PermitUtils :: importShared :: Invalid input type, expected ImportSharedPermitOptions, object, or string"
1936
- );
2084
+ throw new Error("Invalid input type, expected ImportSharedPermitOptions, object, or string");
1937
2085
  }
1938
2086
  if (parsedOptions.type != null && parsedOptions.type !== "sharing") {
1939
- throw new Error(`PermitUtils :: importShared :: Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
2087
+ throw new Error(`Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
1940
2088
  }
1941
2089
  const validation = validateImportPermitOptions({ ...parsedOptions, type: "recipient" });
1942
- if (!validation.success) {
1943
- throw new Error(
1944
- "PermitUtils :: importShared :: Parsing ImportPermitOptions failed " + JSON.stringify(validation.error, null, 2)
1945
- );
1946
- }
1947
2090
  const sealingPair = GenerateSealingKey();
1948
2091
  const permit = {
1949
- ...validation.data,
2092
+ hash: PermitUtils.getHash(validation),
2093
+ ...validation,
1950
2094
  sealingPair,
1951
2095
  _signedDomain: void 0
1952
2096
  };
@@ -1958,11 +2102,11 @@ var PermitUtils = {
1958
2102
  sign: async (permit, publicClient, walletClient) => {
1959
2103
  if (walletClient == null || walletClient.account == null) {
1960
2104
  throw new Error(
1961
- "PermitUtils :: sign - walletClient undefined, you must pass in a `walletClient` for the connected user to create a permit signature"
2105
+ "Missing walletClient, you must pass in a `walletClient` for the connected user to create a permit signature"
1962
2106
  );
1963
2107
  }
1964
2108
  const primaryType = SignatureUtils.getPrimaryType(permit.type);
1965
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
2109
+ const domain = await getAclEIP712Domain(publicClient);
1966
2110
  const { types, message } = SignatureUtils.getSignatureParams(PermitUtils.getPermission(permit, true), primaryType);
1967
2111
  const signature = await walletClient.signTypedData({
1968
2112
  domain,
@@ -2022,6 +2166,7 @@ var PermitUtils = {
2022
2166
  */
2023
2167
  serialize: (permit) => {
2024
2168
  return {
2169
+ hash: permit.hash,
2025
2170
  name: permit.name,
2026
2171
  type: permit.type,
2027
2172
  issuer: permit.issuer,
@@ -2046,7 +2191,7 @@ var PermitUtils = {
2046
2191
  } else if (permit.type === "recipient") {
2047
2192
  return validateImportPermit(permit);
2048
2193
  } else {
2049
- throw new Error("PermitUtils :: validate :: Invalid permit type");
2194
+ throw new Error("Invalid permit type");
2050
2195
  }
2051
2196
  },
2052
2197
  /**
@@ -2054,12 +2199,7 @@ var PermitUtils = {
2054
2199
  */
2055
2200
  getPermission: (permit, skipValidation = false) => {
2056
2201
  if (!skipValidation) {
2057
- const validationResult = PermitUtils.validate(permit);
2058
- if (!validationResult.success) {
2059
- throw new Error(
2060
- `PermitUtils :: getPermission :: permit validation failed - ${JSON.stringify(validationResult.error, null, 2)} ${JSON.stringify(permit, null, 2)}`
2061
- );
2062
- }
2202
+ PermitUtils.validate(permit);
2063
2203
  }
2064
2204
  return {
2065
2205
  issuer: permit.issuer,
@@ -2140,28 +2280,7 @@ var PermitUtils = {
2140
2280
  * Fetch EIP712 domain from the blockchain
2141
2281
  */
2142
2282
  fetchEIP712Domain: async (publicClient) => {
2143
- const TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
2144
- const ACL_IFACE = "function acl() view returns (address)";
2145
- const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
2146
- const aclAbi = viem.parseAbi([ACL_IFACE]);
2147
- const aclAddress = await publicClient.readContract({
2148
- address: TASK_MANAGER_ADDRESS,
2149
- abi: aclAbi,
2150
- functionName: "acl"
2151
- });
2152
- const domainAbi = viem.parseAbi([EIP712_DOMAIN_IFACE]);
2153
- const domain = await publicClient.readContract({
2154
- address: aclAddress,
2155
- abi: domainAbi,
2156
- functionName: "eip712Domain"
2157
- });
2158
- const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
2159
- return {
2160
- name,
2161
- version,
2162
- chainId: Number(chainId),
2163
- verifyingContract
2164
- };
2283
+ return getAclEIP712Domain(publicClient);
2165
2284
  },
2166
2285
  /**
2167
2286
  * Check if permit's signed domain matches the provided domain
@@ -2175,8 +2294,15 @@ var PermitUtils = {
2175
2294
  checkSignedDomainValid: async (permit, publicClient) => {
2176
2295
  if (permit._signedDomain == null)
2177
2296
  return false;
2178
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
2297
+ const domain = await getAclEIP712Domain(publicClient);
2179
2298
  return PermitUtils.matchesDomain(permit, domain);
2299
+ },
2300
+ /**
2301
+ * Check if permit passes the on-chain validation
2302
+ */
2303
+ checkValidityOnChain: async (permit, publicClient) => {
2304
+ const permission = PermitUtils.getPermission(permit);
2305
+ return checkPermitValidityOnChain(permission, publicClient);
2180
2306
  }
2181
2307
  };
2182
2308
  var PERMIT_STORE_DEFAULTS = {
@@ -2230,11 +2356,11 @@ var setPermit = (chainId, account, permit) => {
2230
2356
  state.permits[chainId] = {};
2231
2357
  if (state.permits[chainId][account] == null)
2232
2358
  state.permits[chainId][account] = {};
2233
- state.permits[chainId][account][PermitUtils.getHash(permit)] = PermitUtils.serialize(permit);
2359
+ state.permits[chainId][account][permit.hash] = PermitUtils.serialize(permit);
2234
2360
  })
2235
2361
  );
2236
2362
  };
2237
- var removePermit = (chainId, account, hash, force) => {
2363
+ var removePermit = (chainId, account, hash) => {
2238
2364
  clearStaleStore();
2239
2365
  _permitStore.setState(
2240
2366
  immer.produce((state) => {
@@ -2248,15 +2374,7 @@ var removePermit = (chainId, account, hash, force) => {
2248
2374
  if (accountPermits[hash] == null)
2249
2375
  return;
2250
2376
  if (state.activePermitHash[chainId][account] === hash) {
2251
- const otherPermitHash = Object.keys(accountPermits).find((key) => key !== hash && accountPermits[key] != null);
2252
- if (otherPermitHash) {
2253
- state.activePermitHash[chainId][account] = otherPermitHash;
2254
- } else {
2255
- if (!force) {
2256
- throw new Error("Cannot remove the last permit without force flag");
2257
- }
2258
- state.activePermitHash[chainId][account] = void 0;
2259
- }
2377
+ state.activePermitHash[chainId][account] = void 0;
2260
2378
  }
2261
2379
  accountPermits[hash] = void 0;
2262
2380
  })
@@ -2307,7 +2425,7 @@ var storeActivePermit = async (permit, publicClient, walletClient) => {
2307
2425
  const chainId = await publicClient.getChainId();
2308
2426
  const account = walletClient.account.address;
2309
2427
  permitStore.setPermit(chainId, account, permit);
2310
- permitStore.setActivePermitHash(chainId, account, PermitUtils.getHash(permit));
2428
+ permitStore.setActivePermitHash(chainId, account, permit.hash);
2311
2429
  };
2312
2430
  var createPermitWithSign = async (options, publicClient, walletClient, permitMethod) => {
2313
2431
  const permit = await permitMethod(options, publicClient, walletClient);
@@ -2365,7 +2483,7 @@ var getOrCreateSharingPermit = async (publicClient, walletClient, options, chain
2365
2483
  }
2366
2484
  return createSharing(options, publicClient, walletClient);
2367
2485
  };
2368
- var removePermit2 = async (chainId, account, hash, force) => permitStore.removePermit(chainId, account, hash, force);
2486
+ var removePermit2 = async (chainId, account, hash) => permitStore.removePermit(chainId, account, hash);
2369
2487
  var removeActivePermit = async (chainId, account) => permitStore.removeActivePermitHash(chainId, account);
2370
2488
  var permits = {
2371
2489
  getSnapshot: permitStore.store.getState,
@@ -2537,7 +2655,6 @@ var MockQueryDecrypterAbi = [
2537
2655
  ];
2538
2656
 
2539
2657
  // core/decrypt/cofheMocksSealOutput.ts
2540
- var MockQueryDecrypterAddress = "0x0000000000000000000000000000000000000200";
2541
2658
  async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSealOutputDelay) {
2542
2659
  if (mocksSealOutputDelay > 0)
2543
2660
  await sleep(mocksSealOutputDelay);
@@ -2548,7 +2665,7 @@ async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSe
2548
2665
  validatorId: BigInt(permission.validatorId)
2549
2666
  };
2550
2667
  const [allowed, error, result] = await publicClient.readContract({
2551
- address: MockQueryDecrypterAddress,
2668
+ address: MOCKS_QUERY_DECRYPTER_ADDRESS,
2552
2669
  abi: MockQueryDecrypterAbi,
2553
2670
  functionName: "querySealOutput",
2554
2671
  args: [ctHash, BigInt(utype), permissionWithBigInts]
@@ -3008,6 +3125,7 @@ var InitialConnectStore = {
3008
3125
  function createCofhesdkClientBase(opts) {
3009
3126
  const keysStorage = createKeysStore(opts.config.fheKeyStorage);
3010
3127
  const connectStore = vanilla.createStore(() => InitialConnectStore);
3128
+ let connectAttemptId = 0;
3011
3129
  const updateConnectState = (partial) => {
3012
3130
  connectStore.setState((state) => ({ ...state, ...partial }));
3013
3131
  };
@@ -3033,6 +3151,8 @@ function createCofhesdkClientBase(opts) {
3033
3151
  const state = connectStore.getState();
3034
3152
  if (state.connected && state.publicClient === publicClient && state.walletClient === walletClient)
3035
3153
  return;
3154
+ connectAttemptId += 1;
3155
+ const localAttemptId = connectAttemptId;
3036
3156
  updateConnectState({
3037
3157
  ...InitialConnectStore,
3038
3158
  connecting: true
@@ -3040,6 +3160,8 @@ function createCofhesdkClientBase(opts) {
3040
3160
  try {
3041
3161
  const chainId = await getPublicClientChainID(publicClient);
3042
3162
  const account = await getWalletClientAccount(walletClient);
3163
+ if (localAttemptId !== connectAttemptId)
3164
+ return;
3043
3165
  updateConnectState({
3044
3166
  connected: true,
3045
3167
  connecting: false,
@@ -3050,6 +3172,8 @@ function createCofhesdkClientBase(opts) {
3050
3172
  walletClient
3051
3173
  });
3052
3174
  } catch (e) {
3175
+ if (localAttemptId !== connectAttemptId)
3176
+ return;
3053
3177
  updateConnectState({
3054
3178
  ...InitialConnectStore,
3055
3179
  connectError: e
@@ -3057,6 +3181,10 @@ function createCofhesdkClientBase(opts) {
3057
3181
  throw e;
3058
3182
  }
3059
3183
  }
3184
+ function disconnect() {
3185
+ connectAttemptId += 1;
3186
+ updateConnectState({ ...InitialConnectStore });
3187
+ }
3060
3188
  function encryptInputs(inputs) {
3061
3189
  const state = connectStore.getState();
3062
3190
  return new EncryptInputsBuilder({
@@ -3161,9 +3289,9 @@ function createCofhesdkClientBase(opts) {
3161
3289
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
3162
3290
  return permits.selectActivePermit(_chainId, _account, hash);
3163
3291
  },
3164
- removePermit: async (hash, chainId, account, force) => {
3292
+ removePermit: async (hash, chainId, account) => {
3165
3293
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
3166
- return permits.removePermit(_chainId, _account, hash, force);
3294
+ return permits.removePermit(_chainId, _account, hash);
3167
3295
  },
3168
3296
  removeActivePermit: async (chainId, account) => {
3169
3297
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
@@ -3188,6 +3316,7 @@ function createCofhesdkClientBase(opts) {
3188
3316
  // config & platform-specific (read-only)
3189
3317
  config: opts.config,
3190
3318
  connect,
3319
+ disconnect,
3191
3320
  encryptInputs,
3192
3321
  decryptHandle,
3193
3322
  permits: clientPermits