@cofhe/sdk 0.6.0 → 0.7.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 (114) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/acps/acp.ts +411 -0
  3. package/acps/index.ts +70 -0
  4. package/{permits → acps}/onchain-utils.ts +49 -24
  5. package/acps/sealing.ts +90 -0
  6. package/acps/signature.ts +89 -0
  7. package/acps/store.ts +172 -0
  8. package/acps/test/acp.test.ts +615 -0
  9. package/acps/test/localstorage.test.ts +105 -0
  10. package/acps/test/sealing.test.ts +77 -0
  11. package/acps/test/store.test.ts +88 -0
  12. package/acps/test/validation.test.ts +361 -0
  13. package/acps/test-utils.ts +32 -0
  14. package/acps/types.ts +252 -0
  15. package/acps/validation.ts +392 -0
  16. package/adapters/test/ethers5.test.ts +4 -1
  17. package/adapters/test/ethers6.test.ts +4 -1
  18. package/adapters/test/wagmi.test.ts +5 -2
  19. package/chains/chains/stagingCofhe.ts +21 -0
  20. package/chains/index.ts +3 -1
  21. package/chains/test/chains.test.ts +2 -1
  22. package/core/acps.ts +625 -0
  23. package/core/client.ts +136 -39
  24. package/core/clientTypes.ts +52 -41
  25. package/core/config.ts +66 -5
  26. package/core/debug.ts +72 -0
  27. package/core/decrypt/MockThresholdNetworkAbi.ts +20 -11
  28. package/core/decrypt/apiError.ts +104 -0
  29. package/core/decrypt/cofheMocksDecryptForTx.ts +11 -11
  30. package/core/decrypt/cofheMocksDecryptForView.ts +7 -7
  31. package/core/decrypt/decryptForTxBuilder.ts +102 -102
  32. package/core/decrypt/decryptForViewBuilder.ts +90 -90
  33. package/core/decrypt/submitRetry.ts +38 -30
  34. package/core/decrypt/tnDecryptV1.ts +5 -5
  35. package/core/decrypt/tnDecryptV2.ts +45 -34
  36. package/core/decrypt/tnSealOutputV1.ts +4 -3
  37. package/core/decrypt/tnSealOutputV2.ts +44 -31
  38. package/core/encrypt/cofheMocksZkVerifySign.ts +59 -74
  39. package/core/encrypt/encryptInputsBuilder.ts +86 -52
  40. package/core/encrypt/zkPackProveVerify.ts +25 -18
  41. package/core/error.ts +34 -6
  42. package/core/index.ts +14 -14
  43. package/core/test/acpDefaults.test.ts +52 -0
  44. package/core/test/acps.test.ts +596 -0
  45. package/core/test/apiError.test.ts +130 -0
  46. package/core/test/client.test.ts +22 -19
  47. package/core/test/config.test.ts +25 -5
  48. package/core/test/decrypt.test.ts +40 -35
  49. package/core/test/decryptBuilders.test.ts +68 -68
  50. package/core/test/decryptErrorCodes.test.ts +217 -0
  51. package/core/test/encryptInputsBuilder.test.ts +72 -41
  52. package/core/test/pollCallbacks.test.ts +89 -18
  53. package/core/test/stagingRedirect.ts +18 -0
  54. package/core/test/submitRetry.test.ts +182 -0
  55. package/core/types.ts +9 -69
  56. package/dist/acp-Wi6isVQI.d.cts +407 -0
  57. package/dist/acp-Wi6isVQI.d.ts +407 -0
  58. package/dist/acps.cjs +1081 -0
  59. package/dist/acps.d.cts +480 -0
  60. package/dist/acps.d.ts +480 -0
  61. package/dist/acps.js +2 -0
  62. package/dist/chains.cjs +14 -1
  63. package/dist/chains.d.cts +30 -1
  64. package/dist/chains.d.ts +30 -1
  65. package/dist/chains.js +1 -1
  66. package/dist/{chunk-PE5V5CCV.js → chunk-43USWPEH.js} +1000 -604
  67. package/dist/{chunk-MTRAXQXC.js → chunk-N6IDQRRU.js} +14 -2
  68. package/dist/chunk-Q7CBWGQX.js +1029 -0
  69. package/dist/{clientTypes-CyUvRRzA.d.ts → clientTypes-BN3nbzYM.d.ts} +342 -165
  70. package/dist/{clientTypes-BDy1qIBu.d.cts → clientTypes-CYZjFznO.d.cts} +342 -165
  71. package/dist/core.cjs +1431 -1026
  72. package/dist/core.d.cts +55 -10
  73. package/dist/core.d.ts +55 -10
  74. package/dist/core.js +3 -3
  75. package/dist/node.cjs +1356 -976
  76. package/dist/node.d.cts +2 -2
  77. package/dist/node.d.ts +2 -2
  78. package/dist/node.js +3 -3
  79. package/dist/web.cjs +1356 -976
  80. package/dist/web.d.cts +2 -2
  81. package/dist/web.d.ts +2 -2
  82. package/dist/web.js +3 -3
  83. package/node/test/inherited.test.ts +75 -65
  84. package/node/test/tfheinit.test.ts +23 -8
  85. package/package.json +6 -6
  86. package/web/test/client.web.test.ts +5 -1
  87. package/web/test/inherited.web.test.ts +75 -65
  88. package/web/test/tfheinit.web.test.ts +14 -5
  89. package/web/test/worker.config.web.test.ts +38 -23
  90. package/web/test/worker.output.web.test.ts +25 -24
  91. package/core/encrypt/encryptUtils.ts +0 -67
  92. package/core/permits.ts +0 -206
  93. package/core/test/permits.test.ts +0 -534
  94. package/dist/chunk-VB62WYPL.js +0 -978
  95. package/dist/permit-DnVMDT5h.d.cts +0 -376
  96. package/dist/permit-DnVMDT5h.d.ts +0 -376
  97. package/dist/permits.cjs +0 -1026
  98. package/dist/permits.d.cts +0 -353
  99. package/dist/permits.d.ts +0 -353
  100. package/dist/permits.js +0 -2
  101. package/permits/index.ts +0 -68
  102. package/permits/permit.ts +0 -385
  103. package/permits/sealing.ts +0 -131
  104. package/permits/signature.ts +0 -79
  105. package/permits/store.ts +0 -157
  106. package/permits/test/localstorage.test.ts +0 -113
  107. package/permits/test/permit.test.ts +0 -557
  108. package/permits/test/sealing.test.ts +0 -84
  109. package/permits/test/store.test.ts +0 -88
  110. package/permits/test/validation.test.ts +0 -361
  111. package/permits/test-utils.ts +0 -28
  112. package/permits/types.ts +0 -204
  113. package/permits/validation.ts +0 -327
  114. /package/{permits → acps}/utils.ts +0 -0
package/dist/core.cjs CHANGED
@@ -16,58 +16,78 @@ var nacl__default = /*#__PURE__*/_interopDefault(nacl);
16
16
  // core/client.ts
17
17
 
18
18
  // core/error.ts
19
- var CofheErrorCode = /* @__PURE__ */ ((CofheErrorCode3) => {
20
- CofheErrorCode3["InternalError"] = "INTERNAL_ERROR";
21
- CofheErrorCode3["UnknownEnvironment"] = "UNKNOWN_ENVIRONMENT";
22
- CofheErrorCode3["InitTfheFailed"] = "INIT_TFHE_FAILED";
23
- CofheErrorCode3["InitViemFailed"] = "INIT_VIEM_FAILED";
24
- CofheErrorCode3["InitEthersFailed"] = "INIT_ETHERS_FAILED";
25
- CofheErrorCode3["NotConnected"] = "NOT_CONNECTED";
26
- CofheErrorCode3["MissingPublicClient"] = "MISSING_PUBLIC_CLIENT";
27
- CofheErrorCode3["MissingWalletClient"] = "MISSING_WALLET_CLIENT";
28
- CofheErrorCode3["MissingProviderParam"] = "MISSING_PROVIDER_PARAM";
29
- CofheErrorCode3["EmptySecurityZonesParam"] = "EMPTY_SECURITY_ZONES_PARAM";
30
- CofheErrorCode3["InvalidPermitData"] = "INVALID_PERMIT_DATA";
31
- CofheErrorCode3["InvalidPermitDomain"] = "INVALID_PERMIT_DOMAIN";
32
- CofheErrorCode3["PermitNotFound"] = "PERMIT_NOT_FOUND";
33
- CofheErrorCode3["CannotRemoveLastPermit"] = "CANNOT_REMOVE_LAST_PERMIT";
34
- CofheErrorCode3["AccountUninitialized"] = "ACCOUNT_UNINITIALIZED";
35
- CofheErrorCode3["ChainIdUninitialized"] = "CHAIN_ID_UNINITIALIZED";
36
- CofheErrorCode3["SealOutputFailed"] = "SEAL_OUTPUT_FAILED";
37
- CofheErrorCode3["SealOutputReturnedNull"] = "SEAL_OUTPUT_RETURNED_NULL";
38
- CofheErrorCode3["InvalidUtype"] = "INVALID_UTYPE";
39
- CofheErrorCode3["DecryptFailed"] = "DECRYPT_FAILED";
40
- CofheErrorCode3["DecryptReturnedNull"] = "DECRYPT_RETURNED_NULL";
41
- CofheErrorCode3["ZkMocksInsertCtHashesFailed"] = "ZK_MOCKS_INSERT_CT_HASHES_FAILED";
42
- CofheErrorCode3["ZkMocksCalcCtHashesFailed"] = "ZK_MOCKS_CALC_CT_HASHES_FAILED";
43
- CofheErrorCode3["ZkMocksVerifySignFailed"] = "ZK_MOCKS_VERIFY_SIGN_FAILED";
44
- CofheErrorCode3["ZkMocksCreateProofSignatureFailed"] = "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED";
45
- CofheErrorCode3["ZkVerifyFailed"] = "ZK_VERIFY_FAILED";
46
- CofheErrorCode3["ZkPackFailed"] = "ZK_PACK_FAILED";
47
- CofheErrorCode3["ZkProveFailed"] = "ZK_PROVE_FAILED";
48
- CofheErrorCode3["EncryptRemainingInItems"] = "ENCRYPT_REMAINING_IN_ITEMS";
49
- CofheErrorCode3["ZkUninitialized"] = "ZK_UNINITIALIZED";
50
- CofheErrorCode3["ZkVerifierUrlUninitialized"] = "ZK_VERIFIER_URL_UNINITIALIZED";
51
- CofheErrorCode3["ThresholdNetworkUrlUninitialized"] = "THRESHOLD_NETWORK_URL_UNINITIALIZED";
52
- CofheErrorCode3["MissingConfig"] = "MISSING_CONFIG";
53
- CofheErrorCode3["UnsupportedChain"] = "UNSUPPORTED_CHAIN";
54
- CofheErrorCode3["MissingZkBuilderAndCrsGenerator"] = "MISSING_ZK_BUILDER_AND_CRS_GENERATOR";
55
- CofheErrorCode3["MissingTfhePublicKeyDeserializer"] = "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER";
56
- CofheErrorCode3["MissingCompactPkeCrsDeserializer"] = "MISSING_COMPACT_PKE_CRS_DESERIALIZER";
57
- CofheErrorCode3["MissingFheKey"] = "MISSING_FHE_KEY";
58
- CofheErrorCode3["MissingCrs"] = "MISSING_CRS";
59
- CofheErrorCode3["FetchKeysFailed"] = "FETCH_KEYS_FAILED";
60
- CofheErrorCode3["PublicWalletGetChainIdFailed"] = "PUBLIC_WALLET_GET_CHAIN_ID_FAILED";
61
- CofheErrorCode3["PublicWalletGetAddressesFailed"] = "PUBLIC_WALLET_GET_ADDRESSES_FAILED";
62
- CofheErrorCode3["RehydrateKeysStoreFailed"] = "REHYDRATE_KEYS_STORE_FAILED";
63
- return CofheErrorCode3;
19
+ var CofheErrorCode = /* @__PURE__ */ ((CofheErrorCode2) => {
20
+ CofheErrorCode2["InternalError"] = "INTERNAL_ERROR";
21
+ CofheErrorCode2["UnknownEnvironment"] = "UNKNOWN_ENVIRONMENT";
22
+ CofheErrorCode2["InitTfheFailed"] = "INIT_TFHE_FAILED";
23
+ CofheErrorCode2["InitViemFailed"] = "INIT_VIEM_FAILED";
24
+ CofheErrorCode2["InitEthersFailed"] = "INIT_ETHERS_FAILED";
25
+ CofheErrorCode2["NotConnected"] = "NOT_CONNECTED";
26
+ CofheErrorCode2["MissingPublicClient"] = "MISSING_PUBLIC_CLIENT";
27
+ CofheErrorCode2["MissingWalletClient"] = "MISSING_WALLET_CLIENT";
28
+ CofheErrorCode2["MissingProviderParam"] = "MISSING_PROVIDER_PARAM";
29
+ CofheErrorCode2["EmptySecurityZonesParam"] = "EMPTY_SECURITY_ZONES_PARAM";
30
+ CofheErrorCode2["InvalidACPData"] = "INVALID_ACP_DATA";
31
+ CofheErrorCode2["InvalidACPDomain"] = "INVALID_ACP_DOMAIN";
32
+ CofheErrorCode2["ACPNotFound"] = "ACP_NOT_FOUND";
33
+ CofheErrorCode2["CannotRemoveLastACP"] = "CANNOT_REMOVE_LAST_ACP";
34
+ CofheErrorCode2["AccountUninitialized"] = "ACCOUNT_UNINITIALIZED";
35
+ CofheErrorCode2["ChainIdUninitialized"] = "CHAIN_ID_UNINITIALIZED";
36
+ CofheErrorCode2["ConsumingContractUninitialized"] = "CONSUMING_CONTRACT_UNINITIALIZED";
37
+ CofheErrorCode2["SealOutputFailed"] = "SEAL_OUTPUT_FAILED";
38
+ CofheErrorCode2["SealOutputReturnedNull"] = "SEAL_OUTPUT_RETURNED_NULL";
39
+ CofheErrorCode2["InvalidUtype"] = "INVALID_UTYPE";
40
+ CofheErrorCode2["DecryptFailed"] = "DECRYPT_FAILED";
41
+ CofheErrorCode2["DecryptReturnedNull"] = "DECRYPT_RETURNED_NULL";
42
+ CofheErrorCode2["ZkMocksInsertCtHashesFailed"] = "ZK_MOCKS_INSERT_CT_HASHES_FAILED";
43
+ CofheErrorCode2["ZkMocksCalcCtHashesFailed"] = "ZK_MOCKS_CALC_CT_HASHES_FAILED";
44
+ CofheErrorCode2["ZkMocksVerifySignFailed"] = "ZK_MOCKS_VERIFY_SIGN_FAILED";
45
+ CofheErrorCode2["ZkMocksCreateProofSignatureFailed"] = "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED";
46
+ CofheErrorCode2["ZkVerifyFailed"] = "ZK_VERIFY_FAILED";
47
+ CofheErrorCode2["ZkPackFailed"] = "ZK_PACK_FAILED";
48
+ CofheErrorCode2["ZkProveFailed"] = "ZK_PROVE_FAILED";
49
+ CofheErrorCode2["EncryptRemainingInItems"] = "ENCRYPT_REMAINING_IN_ITEMS";
50
+ CofheErrorCode2["ZkUninitialized"] = "ZK_UNINITIALIZED";
51
+ CofheErrorCode2["ZkVerifierUrlUninitialized"] = "ZK_VERIFIER_URL_UNINITIALIZED";
52
+ CofheErrorCode2["ThresholdNetworkUrlUninitialized"] = "THRESHOLD_NETWORK_URL_UNINITIALIZED";
53
+ CofheErrorCode2["MissingConfig"] = "MISSING_CONFIG";
54
+ CofheErrorCode2["UnsupportedChain"] = "UNSUPPORTED_CHAIN";
55
+ CofheErrorCode2["MissingZkBuilderAndCrsGenerator"] = "MISSING_ZK_BUILDER_AND_CRS_GENERATOR";
56
+ CofheErrorCode2["MissingTfhePublicKeyDeserializer"] = "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER";
57
+ CofheErrorCode2["MissingCompactPkeCrsDeserializer"] = "MISSING_COMPACT_PKE_CRS_DESERIALIZER";
58
+ CofheErrorCode2["MissingFheKey"] = "MISSING_FHE_KEY";
59
+ CofheErrorCode2["MissingCrs"] = "MISSING_CRS";
60
+ CofheErrorCode2["FetchKeysFailed"] = "FETCH_KEYS_FAILED";
61
+ CofheErrorCode2["PublicWalletGetChainIdFailed"] = "PUBLIC_WALLET_GET_CHAIN_ID_FAILED";
62
+ CofheErrorCode2["PublicWalletGetAddressesFailed"] = "PUBLIC_WALLET_GET_ADDRESSES_FAILED";
63
+ CofheErrorCode2["RehydrateKeysStoreFailed"] = "REHYDRATE_KEYS_STORE_FAILED";
64
+ CofheErrorCode2["BadRequest"] = "BAD_REQUEST";
65
+ CofheErrorCode2["UnknownChain"] = "UNKNOWN_CHAIN";
66
+ CofheErrorCode2["ACPMalformed"] = "ACP_MALFORMED";
67
+ CofheErrorCode2["ACPDenied"] = "ACP_DENIED";
68
+ CofheErrorCode2["ACPExpired"] = "ACP_EXPIRED";
69
+ CofheErrorCode2["ACPInvalid"] = "ACP_INVALID";
70
+ CofheErrorCode2["ACPRevoked"] = "ACP_REVOKED";
71
+ CofheErrorCode2["NotPubliclyAllowed"] = "NOT_PUBLICLY_ALLOWED";
72
+ CofheErrorCode2["CtNotFound"] = "CT_NOT_FOUND";
73
+ CofheErrorCode2["UnsupportedSecurityZone"] = "UNSUPPORTED_SECURITY_ZONE";
74
+ CofheErrorCode2["UnsupportedType"] = "UNSUPPORTED_TYPE";
75
+ CofheErrorCode2["SigningFailed"] = "SIGNING_FAILED";
76
+ CofheErrorCode2["CtSourceError"] = "CT_SOURCE_ERROR";
77
+ CofheErrorCode2["ACPVerifierError"] = "ACP_VERIFIER_ERROR";
78
+ CofheErrorCode2["CtSourceTimeout"] = "CT_SOURCE_TIMEOUT";
79
+ CofheErrorCode2["ACPVerifierTimeout"] = "ACP_VERIFIER_TIMEOUT";
80
+ CofheErrorCode2["ACPRequired"] = "ACP_REQUIRED";
81
+ CofheErrorCode2["SealFailed"] = "SEAL_FAILED";
82
+ return CofheErrorCode2;
64
83
  })(CofheErrorCode || {});
65
84
  var CofheError = class _CofheError extends Error {
66
85
  code;
67
86
  cause;
68
87
  hint;
69
88
  context;
70
- constructor({ code, message, cause, hint, context }) {
89
+ apiErrorCode;
90
+ constructor({ code, message, cause, hint, context, apiErrorCode }) {
71
91
  const fullMessage = cause ? `${message} | Caused by: ${cause.message}` : message;
72
92
  super(fullMessage);
73
93
  this.name = "CofheError";
@@ -75,6 +95,7 @@ var CofheError = class _CofheError extends Error {
75
95
  this.cause = cause;
76
96
  this.hint = hint;
77
97
  this.context = context;
98
+ this.apiErrorCode = apiErrorCode;
78
99
  if (Error.captureStackTrace) {
79
100
  Error.captureStackTrace(this, _CofheError);
80
101
  }
@@ -93,6 +114,7 @@ var CofheError = class _CofheError extends Error {
93
114
  message: wrapperError?.message ?? "An internal error occurred",
94
115
  hint: wrapperError?.hint,
95
116
  context: wrapperError?.context,
117
+ apiErrorCode: wrapperError?.apiErrorCode,
96
118
  cause
97
119
  });
98
120
  }
@@ -106,6 +128,7 @@ var CofheError = class _CofheError extends Error {
106
128
  message: this.message,
107
129
  hint: this.hint,
108
130
  context: this.context,
131
+ apiErrorCode: this.apiErrorCode,
109
132
  cause: this.cause ? {
110
133
  name: this.cause.name,
111
134
  message: this.cause.message,
@@ -118,7 +141,8 @@ var CofheError = class _CofheError extends Error {
118
141
  * Returns a human-readable string representation of the error
119
142
  */
120
143
  toString() {
121
- const parts = [`${this.name} [${this.code}]: ${this.message}`];
144
+ const codeSuffix = this.apiErrorCode ? ` (api: ${this.apiErrorCode})` : "";
145
+ const parts = [`${this.name} [${this.code}]${codeSuffix}: ${this.message}`];
122
146
  if (this.hint) {
123
147
  parts.push(`Hint: ${this.hint}`);
124
148
  }
@@ -215,10 +239,6 @@ var FheAllUTypes = [
215
239
  // FheTypes.Uint256,
216
240
  7 /* Uint160 */
217
241
  ];
218
- function assertCorrectEncryptedItemInput(input) {
219
- if (!input.signature.startsWith("0x"))
220
- throw new Error("Signature must be a hex string starting with 0x");
221
- }
222
242
  var EncryptableFactoriesImpl = {
223
243
  bool: (data, securityZone = 0) => ({ data, securityZone, utype: 0 /* Bool */ }),
224
244
  address: (data, securityZone = 0) => ({ data, securityZone, utype: 7 /* Uint160 */ }),
@@ -498,18 +518,19 @@ var constructZkPoKMetadata = (accountAddr, securityZone, chainId) => {
498
518
  metadata.set(chainIdBytes, 1 + accountBytes.length);
499
519
  return metadata;
500
520
  };
501
- var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chainId) => {
521
+ var zkVerifyBatch = async (verifierUrl, serializedBytes, address, securityZone, chainId, consumingContract) => {
502
522
  const packed_list = toHexString(serializedBytes);
503
523
  const sz_byte = new Uint8Array([securityZone]);
504
524
  const payload = {
505
525
  packed_list,
506
526
  account_addr: address,
507
527
  security_zone: sz_byte[0],
508
- chain_id: chainId
528
+ chain_id: chainId,
529
+ contract_address: consumingContract
509
530
  };
510
531
  const body = JSON.stringify(payload);
511
532
  try {
512
- const response = await fetch(`${verifierUrl}/verify`, {
533
+ const response = await fetch(`${verifierUrl}/verifyBatch`, {
513
534
  method: "POST",
514
535
  headers: {
515
536
  "Content-Type": "application/json"
@@ -520,26 +541,25 @@ var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chain
520
541
  const errorBody = await response.text();
521
542
  throw new CofheError({
522
543
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
523
- message: `HTTP error! ZK proof verification failed - ${errorBody}`
544
+ message: `HTTP error! ZK batch proof verification failed - ${errorBody}`
524
545
  });
525
546
  }
526
547
  const json = await response.json();
527
548
  if (json.status !== "success") {
528
549
  throw new CofheError({
529
550
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
530
- message: `ZK proof verification response malformed - ${json.error}`
551
+ message: `ZK batch proof verification response malformed - ${json.error}`
531
552
  });
532
553
  }
533
- return json.data.map(({ ct_hash, signature, recid }) => {
534
- return {
535
- ct_hash,
536
- signature: concatSigRecid(signature, recid)
537
- };
538
- });
554
+ const { ciphertexts, signature, recid } = json.data;
555
+ return {
556
+ outputs: ciphertexts,
557
+ signature: concatSigRecid(signature, recid)
558
+ };
539
559
  } catch (e) {
540
560
  throw new CofheError({
541
561
  code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
542
- message: `ZK proof verification failed`,
562
+ message: `ZK batch proof verification failed`,
543
563
  cause: e instanceof Error ? e : void 0
544
564
  });
545
565
  }
@@ -784,67 +804,59 @@ async function insertCtHashes(items, walletClient) {
784
804
  });
785
805
  }
786
806
  }
787
- async function createProofSignatures(items, securityZone, account) {
788
- let signatures = [];
789
- let encInputSignerClient;
807
+ async function createBatchProofSignature(items, securityZone, account, consumingContract) {
790
808
  try {
791
- encInputSignerClient = createMockZkVerifierSigner();
792
- } catch (err) {
793
- throw new CofheError({
794
- code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
795
- message: `mockZkVerifySign createProofSignatures failed while creating wallet client`,
796
- cause: err instanceof Error ? err : void 0,
797
- context: {
798
- MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY
799
- }
809
+ const itemHashes = items.map(
810
+ (item) => viem.keccak256(
811
+ viem.encodePacked(
812
+ ["uint256", "uint8", "uint8", "address", "uint256", "address"],
813
+ [
814
+ BigInt(item.ctHash),
815
+ item.utype,
816
+ securityZone,
817
+ account,
818
+ BigInt(chains.hardhat.id),
819
+ consumingContract
820
+ ]
821
+ )
822
+ )
823
+ );
824
+ const batchDigest = viem.keccak256(
825
+ viem.encodePacked(
826
+ itemHashes.map(() => "bytes32"),
827
+ itemHashes
828
+ )
829
+ );
830
+ return await accounts.sign({
831
+ hash: batchDigest,
832
+ privateKey: MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY,
833
+ to: "hex"
800
834
  });
801
- }
802
- try {
803
- for (const item of items) {
804
- const packedData = viem.encodePacked(
805
- ["uint256", "uint8", "uint8", "address", "uint256"],
806
- [BigInt(item.ctHash), item.utype, securityZone, account, BigInt(chains.hardhat.id)]
807
- );
808
- const messageHash = viem.keccak256(packedData);
809
- const signature = await accounts.sign({
810
- hash: messageHash,
811
- privateKey: MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY,
812
- to: "hex"
813
- });
814
- signatures.push(signature);
815
- }
816
835
  } catch (err) {
817
836
  throw new CofheError({
818
837
  code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
819
- message: `mockZkVerifySign createProofSignatures failed while calling signMessage`,
838
+ message: `mockZkVerifySign createBatchProofSignature failed while signing the batch digest`,
820
839
  cause: err instanceof Error ? err : void 0,
821
840
  context: {
822
841
  items,
823
- securityZone
824
- }
825
- });
826
- }
827
- if (signatures.length !== items.length) {
828
- throw new CofheError({
829
- code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
830
- message: `mockZkVerifySign createProofSignatures returned incorrect number of signatures`,
831
- context: {
832
- items,
833
- securityZone
842
+ securityZone,
843
+ consumingContract
834
844
  }
835
845
  });
836
846
  }
837
- return signatures;
838
847
  }
839
- async function cofheMocksZkVerifySign(items, account, securityZone, publicClient, walletClient, zkvWalletClient) {
848
+ async function cofheMocksZkVerifySign(items, account, securityZone, consumingContract, publicClient, walletClient, zkvWalletClient) {
840
849
  const _walletClient = zkvWalletClient ?? createMockZkVerifierSigner();
841
850
  const encryptableItems = await calcCtHashes(items, account, securityZone, publicClient);
842
851
  await insertCtHashes(encryptableItems, _walletClient);
843
- const signatures = await createProofSignatures(encryptableItems, securityZone, account);
844
- return encryptableItems.map((item, index) => ({
845
- ct_hash: item.ctHash.toString(),
846
- signature: signatures[index]
847
- }));
852
+ const signature = await createBatchProofSignature(encryptableItems, securityZone, account, consumingContract);
853
+ return {
854
+ outputs: encryptableItems.map((item) => ({
855
+ ct_hash: item.ctHash.toString(),
856
+ ct_type: item.utype
857
+ })),
858
+ signature
859
+ };
848
860
  }
849
861
  var EnvironmentSchema = zod.z.enum(["MOCK", "TESTNET", "MAINNET"]);
850
862
  var CofheChainSchema = zod.z.object({
@@ -887,8 +899,8 @@ var CofheConfigSchema = zod.z.object({
887
899
  environment: zod.z.enum(["node", "hardhat", "web", "react"]).optional().default("node"),
888
900
  /** List of supported chain configurations */
889
901
  supportedChains: zod.z.array(zod.z.custom()),
890
- /** Default permit expiration in seconds, default is 30 days */
891
- defaultPermitExpiration: zod.z.number().optional().default(60 * 60 * 24 * 30),
902
+ /** Default acp expiration in seconds, default is 30 days */
903
+ defaultACPExpiration: zod.z.number().optional().default(60 * 60 * 24 * 30),
892
904
  /** Storage method for fhe keys (defaults to indexedDB on web, filesystem on node) */
893
905
  fheKeyStorage: zod.z.object({
894
906
  getItem: zod.z.custom((val) => typeof val === "function", {
@@ -903,6 +915,12 @@ var CofheConfigSchema = zod.z.object({
903
915
  }).or(zod.z.null()).default(null),
904
916
  /** Whether to use Web Workers for ZK proof generation (web platform only) */
905
917
  useWorkers: zod.z.boolean().optional().default(true),
918
+ /** ACP acp defaults */
919
+ acp: zod.z.object({
920
+ defaultRevoker: zod.z.custom().optional(),
921
+ defaultContractScopes: zod.z.custom().optional(),
922
+ sharingRegistry: zod.z.custom().optional()
923
+ }).optional().default({}),
906
924
  /** Mocks configs */
907
925
  mocks: zod.z.object({
908
926
  decryptDelay: zod.z.number().optional().default(0),
@@ -913,8 +931,19 @@ var CofheConfigSchema = zod.z.object({
913
931
  zkvWalletClient: zod.z.any().optional()
914
932
  }).optional()
915
933
  });
934
+ var RENAMED_COFHE_CONFIG_KEYS = {
935
+ defaultPermitExpiration: "defaultACPExpiration"
936
+ };
937
+ function assertNoRenamedConfigKeys(config, renamedKeys, label) {
938
+ const stale = Object.keys(config).filter((key) => key in renamedKeys);
939
+ if (stale.length === 0)
940
+ return;
941
+ const renames = stale.map((key) => `\`${key}\` is now \`${renamedKeys[key]}\``).join("; ");
942
+ throw new Error(`Invalid ${label}: ${renames}. See the v0.7.0 migration guide.`);
943
+ }
916
944
  function createCofheConfigBase(config) {
917
- const result = CofheConfigSchema.safeParse(config);
945
+ assertNoRenamedConfigKeys(config, RENAMED_COFHE_CONFIG_KEYS, "cofhe configuration");
946
+ const result = CofheConfigSchema.strict().safeParse(config);
918
947
  if (!result.success) {
919
948
  throw new Error(`Invalid cofhe configuration: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
920
949
  }
@@ -1266,9 +1295,9 @@ var BaseBuilder = class {
1266
1295
  // core/encrypt/encryptInputsBuilder.ts
1267
1296
  var EncryptInputsBuilder = class extends BaseBuilder {
1268
1297
  securityZone;
1298
+ consumingContract;
1269
1299
  stepCallback;
1270
1300
  inputItems;
1271
- hpp = false;
1272
1301
  zkvWalletClient;
1273
1302
  tfhePublicKeyDeserializer;
1274
1303
  compactPkeCrsDeserializer;
@@ -1335,20 +1364,6 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1335
1364
  this.keysStorage = params.keysStorage;
1336
1365
  this.useWorker = params.config?.useWorkers ?? true;
1337
1366
  }
1338
- /**
1339
- * @param account - Account that will create the tx using the encrypted inputs.
1340
- *
1341
- * If not provided, the account will be fetched from the connected walletClient.
1342
- *
1343
- * Example:
1344
- * ```typescript
1345
- * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1346
- * .setAccount("0x123")
1347
- * .execute();
1348
- * ```
1349
- *
1350
- * @returns The chainable EncryptInputsBuilder instance.
1351
- */
1352
1367
  setAccount(account) {
1353
1368
  this.account = account;
1354
1369
  return this;
@@ -1356,20 +1371,6 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1356
1371
  getAccount() {
1357
1372
  return this.account;
1358
1373
  }
1359
- /**
1360
- * @param chainId - Chain that will consume the encrypted inputs.
1361
- *
1362
- * If not provided, the chainId will be fetched from the connected publicClient.
1363
- *
1364
- * Example:
1365
- * ```typescript
1366
- * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1367
- * .setChainId(11155111)
1368
- * .execute();
1369
- * ```
1370
- *
1371
- * @returns The chainable EncryptInputsBuilder instance.
1372
- */
1373
1374
  setChainId(chainId) {
1374
1375
  this.chainId = chainId;
1375
1376
  return this;
@@ -1377,20 +1378,6 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1377
1378
  getChainId() {
1378
1379
  return this.chainId;
1379
1380
  }
1380
- /**
1381
- * @param securityZone - Security zone to encrypt the inputs for.
1382
- *
1383
- * If not provided, the default securityZone 0 will be used.
1384
- *
1385
- * Example:
1386
- * ```typescript
1387
- * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1388
- * .setSecurityZone(1)
1389
- * .execute();
1390
- * ```
1391
- *
1392
- * @returns The chainable EncryptInputsBuilder instance.
1393
- */
1394
1381
  setSecurityZone(securityZone) {
1395
1382
  this.securityZone = securityZone;
1396
1383
  return this;
@@ -1399,33 +1386,44 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1399
1386
  return this.securityZone;
1400
1387
  }
1401
1388
  /**
1389
+ * @param address - The contract that will consume the resulting hashes+signature (i.e. the
1390
+ * contract that will call `FHE.asEuint*`/`FHE.asEuint*s` with them).
1391
+ *
1392
+ * Required before `execute()` - the verifier binds this address into the signed digest, so a
1393
+ * batch signed for one contract cannot be replayed into another.
1394
+ *
1402
1395
  * Example:
1403
1396
  * ```typescript
1404
1397
  * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1405
- * .asHashPlusProof()
1398
+ * .setConsumingContract("0x123...890")
1406
1399
  * .execute();
1407
1400
  * ```
1408
1401
  *
1409
- * @returns Chainable EncryptInputsBuilder instance that will return a HashPlusProofResult instead of an array of EncryptedItemInputs.
1402
+ * @returns The chainable EncryptInputsBuilder instance.
1410
1403
  */
1411
- asHashPlusProof() {
1412
- this.hpp = true;
1404
+ setConsumingContract(address) {
1405
+ this.consumingContract = address;
1413
1406
  return this;
1414
1407
  }
1408
+ getConsumingContract() {
1409
+ return this.consumingContract;
1410
+ }
1415
1411
  /**
1416
- * @param useWorker - Whether to use Web Workers for ZK proof generation.
1417
- *
1418
- * Overrides the config-level useWorkers setting for this specific encryption.
1419
- *
1420
- * Example:
1421
- * ```typescript
1422
- * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1423
- * .setUseWorker(false)
1424
- * .execute();
1425
- * ```
1426
- *
1427
- * @returns The chainable EncryptInputsBuilder instance.
1412
+ * Asserts that this.consumingContract is populated
1413
+ * @throws {CofheError} If consumingContract is not set
1428
1414
  */
1415
+ assertConsumingContract() {
1416
+ if (this.consumingContract)
1417
+ return;
1418
+ throw new CofheError({
1419
+ code: "CONSUMING_CONTRACT_UNINITIALIZED" /* ConsumingContractUninitialized */,
1420
+ message: "Consuming contract is not set",
1421
+ hint: "Use setConsumingContract(...) to set the contract that will consume the encrypted inputs.",
1422
+ context: {
1423
+ consumingContract: this.consumingContract
1424
+ }
1425
+ });
1426
+ }
1429
1427
  setUseWorker(useWorker) {
1430
1428
  this.useWorker = useWorker;
1431
1429
  return this;
@@ -1446,21 +1444,6 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1446
1444
  getUseWorker() {
1447
1445
  return this.useWorker;
1448
1446
  }
1449
- /**
1450
- * @param callback - Function to be called with the encryption step.
1451
- *
1452
- * Useful for debugging and tracking the progress of the encryption process.
1453
- * Useful for a UI element that shows the progress of the encryption process.
1454
- *
1455
- * Example:
1456
- * ```typescript
1457
- * const encrypted = await encryptInputs([Encryptable.uint128(10n)])
1458
- * .onStep((step: EncryptStep) => console.log(step))
1459
- * .execute();
1460
- * ```
1461
- *
1462
- * @returns The EncryptInputsBuilder instance.
1463
- */
1464
1447
  onStep(callback) {
1465
1448
  this.stepCallback = callback;
1466
1449
  return this;
@@ -1599,6 +1582,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1599
1582
  this.assertAccount();
1600
1583
  this.assertPublicClient();
1601
1584
  this.assertWalletClient();
1585
+ this.assertConsumingContract();
1602
1586
  const [initTfheDelay, fetchKeysDelay, packDelay, proveDelay, verifyDelay] = this.resolveEncryptDelays();
1603
1587
  this.fireStepStart("initTfhe" /* InitTfhe */);
1604
1588
  await sleep(initTfheDelay);
@@ -1624,22 +1608,17 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1624
1608
  this.fireStepEnd("prove" /* Prove */, { isMocks: true, mockSleep: proveDelay });
1625
1609
  this.fireStepStart("verify" /* Verify */);
1626
1610
  await sleep(verifyDelay);
1627
- const signedResults = await cofheMocksZkVerifySign(
1611
+ const result = await cofheMocksZkVerifySign(
1628
1612
  this.inputItems,
1629
1613
  this.account,
1630
1614
  this.securityZone,
1615
+ this.consumingContract,
1631
1616
  this.publicClient,
1632
1617
  this.walletClient,
1633
1618
  this.zkvWalletClient
1634
1619
  );
1635
- const encryptedInputs = signedResults.map(({ ct_hash, signature }, index) => ({
1636
- ctHash: BigInt(ct_hash),
1637
- securityZone: this.securityZone,
1638
- utype: this.inputItems[index].utype,
1639
- signature
1640
- }));
1641
1620
  this.fireStepEnd("verify" /* Verify */, { isMocks: true, mockSleep: verifyDelay });
1642
- return encryptedInputs;
1621
+ return result;
1643
1622
  }
1644
1623
  /**
1645
1624
  * In the production context, perform a true encryption with the CoFHE coprocessor.
@@ -1647,6 +1626,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1647
1626
  async productionExecute() {
1648
1627
  this.assertAccount();
1649
1628
  this.assertChainId();
1629
+ this.assertConsumingContract();
1650
1630
  this.fireStepStart("initTfhe" /* InitTfhe */);
1651
1631
  const tfheInitializationExecuted = await this.initTfheOrThrow();
1652
1632
  this.fireStepEnd("initTfhe" /* InitTfhe */, { tfheInitializationExecuted });
@@ -1681,26 +1661,24 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1681
1661
  });
1682
1662
  this.fireStepStart("verify" /* Verify */);
1683
1663
  const zkVerifierUrl = await this.getZkVerifierUrl();
1684
- const verifyResults = await zkVerify(zkVerifierUrl, proof, this.account, this.securityZone, this.chainId);
1685
- const encryptedInputs = verifyResults.map(
1686
- ({ ct_hash, signature }, index) => ({
1687
- ctHash: BigInt(ct_hash),
1688
- securityZone: this.securityZone,
1689
- utype: this.inputItems[index].utype,
1690
- signature
1691
- })
1664
+ const result = await zkVerifyBatch(
1665
+ zkVerifierUrl,
1666
+ proof,
1667
+ this.account,
1668
+ this.securityZone,
1669
+ this.chainId,
1670
+ this.consumingContract
1692
1671
  );
1693
1672
  this.fireStepEnd("verify" /* Verify */);
1694
- return encryptedInputs;
1695
- }
1696
- structsToHashPlusProof(inItems) {
1697
- let hashes = [];
1698
- let proof = "";
1699
- for (const item of inItems) {
1700
- hashes.push("0x" + item.ctHash.toString(16).padStart(64, "0"));
1701
- proof += item.signature;
1702
- }
1703
- return [...hashes, proof];
1673
+ return result;
1674
+ }
1675
+ /**
1676
+ * Converts a batch-verified result (per-item ctHash/ctType + one shared signature) into the
1677
+ * tuple returned by `execute()`: per-item hashes in input order, followed by the single signature.
1678
+ */
1679
+ buildBatchResult(result) {
1680
+ const hashes = result.outputs.map((output) => "0x" + BigInt(output.ct_hash).toString(16).padStart(64, "0"));
1681
+ return [...hashes, result.signature];
1704
1682
  }
1705
1683
  /**
1706
1684
  * Final step of the encryption process. MUST BE CALLED LAST IN THE CHAIN.
@@ -1722,18 +1700,16 @@ var EncryptInputsBuilder = class extends BaseBuilder {
1722
1700
  * @returns The encrypted inputs.
1723
1701
  */
1724
1702
  async execute() {
1725
- let items;
1703
+ let result;
1726
1704
  if (this.chainId === chains.hardhat.id)
1727
- items = await this.mocksExecute();
1705
+ result = await this.mocksExecute();
1728
1706
  else
1729
- items = await this.productionExecute();
1730
- if (this.hpp)
1731
- return this.structsToHashPlusProof(items);
1732
- return items;
1707
+ result = await this.productionExecute();
1708
+ return this.buildBatchResult(result);
1733
1709
  }
1734
1710
  };
1735
1711
 
1736
- // permits/utils.ts
1712
+ // acps/utils.ts
1737
1713
  var fromHexString = (hexString) => {
1738
1714
  const cleanString = hexString.length % 2 === 1 ? `0${hexString}` : hexString;
1739
1715
  const arr = cleanString.replace(/^0x/, "").match(/.{1,2}/g);
@@ -1753,120 +1729,33 @@ function toBigInt(value) {
1753
1729
  return value;
1754
1730
  }
1755
1731
  }
1756
- function toBeArray(value) {
1757
- const bigIntValue = typeof value === "number" ? BigInt(value) : value;
1758
- const hex = bigIntValue.toString(16);
1759
- const paddedHex = hex.length % 2 === 0 ? hex : "0" + hex;
1760
- return fromHexString(paddedHex);
1761
- }
1762
- function isString(value) {
1763
- if (typeof value !== "string") {
1764
- throw new Error(`Expected value which is \`string\`, received value of type \`${typeof value}\`.`);
1765
- }
1766
- }
1767
- function isNumber(value) {
1768
- const is = typeof value === "number" && !Number.isNaN(value);
1769
- if (!is) {
1770
- throw new Error(`Expected value which is \`number\`, received value of type \`${typeof value}\`.`);
1771
- }
1772
- }
1773
- function isBigIntOrNumber(value) {
1774
- const is = typeof value === "bigint";
1775
- if (!is) {
1776
- try {
1777
- isNumber(value);
1778
- } catch (e) {
1779
- throw new Error(`Value ${value} is not a number or bigint: ${typeof value}`);
1780
- }
1781
- }
1782
- }
1783
1732
 
1784
- // permits/sealing.ts
1785
- var PRIVATE_KEY_LENGTH = 64;
1786
- var PUBLIC_KEY_LENGTH = 64;
1787
- var SealingKey = class _SealingKey {
1788
- /**
1789
- * The private key used for decryption.
1790
- */
1791
- privateKey;
1792
- /**
1793
- * The public key used for encryption.
1794
- */
1795
- publicKey;
1796
- /**
1797
- * Constructs a SealingKey instance with the given private and public keys.
1798
- *
1799
- * @param {string} privateKey - The private key used for decryption.
1800
- * @param {string} publicKey - The public key used for encryption.
1801
- * @throws Will throw an error if the provided keys lengths do not match
1802
- * the required lengths for private and public keys.
1803
- */
1804
- constructor(privateKey, publicKey) {
1805
- if (privateKey.length !== PRIVATE_KEY_LENGTH) {
1806
- throw new Error(`Private key must be of length ${PRIVATE_KEY_LENGTH}`);
1807
- }
1808
- if (publicKey.length !== PUBLIC_KEY_LENGTH) {
1809
- throw new Error(`Public key must be of length ${PUBLIC_KEY_LENGTH}`);
1810
- }
1811
- this.privateKey = privateKey;
1812
- this.publicKey = publicKey;
1813
- }
1814
- unseal = (parsedData) => {
1815
- const nonce = parsedData.nonce instanceof Uint8Array ? parsedData.nonce : new Uint8Array(parsedData.nonce);
1816
- const ephemPublicKey = parsedData.public_key instanceof Uint8Array ? parsedData.public_key : new Uint8Array(parsedData.public_key);
1817
- const dataToDecrypt = parsedData.data instanceof Uint8Array ? parsedData.data : new Uint8Array(parsedData.data);
1818
- const privateKeyBytes = fromHexString(this.privateKey);
1819
- const decryptedMessage = nacl__default.default.box.open(dataToDecrypt, nonce, ephemPublicKey, privateKeyBytes);
1820
- if (!decryptedMessage) {
1821
- throw new Error("Failed to decrypt message");
1822
- }
1823
- return toBigInt(decryptedMessage);
1824
- };
1825
- /**
1826
- * Serializes the SealingKey to a JSON object.
1827
- */
1828
- serialize = () => {
1829
- return {
1830
- privateKey: this.privateKey,
1831
- publicKey: this.publicKey
1832
- };
1833
- };
1834
- /**
1835
- * Deserializes the SealingKey from a JSON object.
1836
- */
1837
- static deserialize = (privateKey, publicKey) => {
1838
- return new _SealingKey(privateKey, publicKey);
1839
- };
1840
- /**
1841
- * Seals (encrypts) the provided message for a receiver with the specified public key.
1842
- *
1843
- * @param {bigint | number} value - The message to be encrypted.
1844
- * @param {string} publicKey - The public key of the intended recipient.
1845
- * @returns string - The encrypted message in hexadecimal format.
1846
- * @static
1847
- * @throws Will throw if the provided publicKey or value do not meet defined preconditions.
1848
- */
1849
- static seal = (value, publicKey) => {
1850
- isString(publicKey);
1851
- isBigIntOrNumber(value);
1852
- const ephemeralKeyPair = nacl__default.default.box.keyPair();
1853
- const nonce = nacl__default.default.randomBytes(nacl__default.default.box.nonceLength);
1854
- const encryptedMessage = nacl__default.default.box(toBeArray(value), nonce, fromHexString(publicKey), ephemeralKeyPair.secretKey);
1855
- return {
1856
- data: encryptedMessage,
1857
- public_key: ephemeralKeyPair.publicKey,
1858
- nonce
1859
- };
1860
- };
1861
- };
1733
+ // acps/sealing.ts
1734
+ var KEY_HEX_LENGTH = 64;
1862
1735
  var GenerateSealingKey = () => {
1863
1736
  const sodiumKeypair = nacl__default.default.box.keyPair();
1864
- return new SealingKey(toHexString2(sodiumKeypair.secretKey), toHexString2(sodiumKeypair.publicKey));
1737
+ return {
1738
+ privateKey: `0x${toHexString2(sodiumKeypair.secretKey)}`,
1739
+ publicKey: `0x${toHexString2(sodiumKeypair.publicKey)}`
1740
+ };
1741
+ };
1742
+ var unsealWithPrivateKey = (privateKey, parsedData) => {
1743
+ assertKeyLength(privateKey, "Private");
1744
+ const nonce = parsedData.nonce instanceof Uint8Array ? parsedData.nonce : new Uint8Array(parsedData.nonce);
1745
+ const ephemPublicKey = parsedData.public_key instanceof Uint8Array ? parsedData.public_key : new Uint8Array(parsedData.public_key);
1746
+ const dataToDecrypt = parsedData.data instanceof Uint8Array ? parsedData.data : new Uint8Array(parsedData.data);
1747
+ const decryptedMessage = nacl__default.default.box.open(dataToDecrypt, nonce, ephemPublicKey, fromHexString(privateKey));
1748
+ if (!decryptedMessage) {
1749
+ throw new Error("Failed to decrypt message");
1750
+ }
1751
+ return toBigInt(decryptedMessage);
1752
+ };
1753
+ var assertKeyLength = (key, kind) => {
1754
+ const bare = key.startsWith("0x") ? key.slice(2) : key;
1755
+ if (bare.length !== KEY_HEX_LENGTH) {
1756
+ throw new Error(`${kind} key must be of length ${KEY_HEX_LENGTH}`);
1757
+ }
1865
1758
  };
1866
- var SerializedSealingPair = zod.z.object({
1867
- privateKey: zod.z.string(),
1868
- publicKey: zod.z.string()
1869
- });
1870
1759
  var addressSchema = zod.z.string().refine((val) => viem.isAddress(val), {
1871
1760
  error: "Invalid address"
1872
1761
  }).transform((val) => viem.getAddress(val));
@@ -1885,46 +1774,70 @@ var bytesNotEmptySchema = bytesSchema.refine((val) => val !== "0x", {
1885
1774
  error: "Must not be empty"
1886
1775
  });
1887
1776
  var DEFAULT_EXPIRATION_FN = () => Math.round(Date.now() / 1e3) + 7 * 24 * 60 * 60;
1888
- var zPermitWithDefaults = zod.z.object({
1889
- name: zod.z.string().optional().default("Unnamed Permit"),
1777
+ var handlesSchema = zod.z.array(zod.z.string().regex(/^0x[0-9a-fA-F]{64}$/, "Invalid handle: expected 32-byte hex")).optional().default([]);
1778
+ var contractsSchema = zod.z.array(addressSchema).optional().default([]);
1779
+ var SCOPE_GLOBAL = 0;
1780
+ var SCOPE_CONTRACT = 1;
1781
+ var SCOPE_HANDLES = 2;
1782
+ var ScopeConsistencyRefinement = [
1783
+ (data) => data.scope === SCOPE_GLOBAL && data.contracts.length === 0 && data.handles.length === 0 || data.scope === SCOPE_CONTRACT && data.contracts.length > 0 && data.handles.length === 0 || data.scope === SCOPE_HANDLES && data.handles.length > 0 && data.contracts.length === 0,
1784
+ {
1785
+ error: "ACP scope :: arrays must match the scope mode (Global: both empty; Contract: contracts only; Handles: handles only)",
1786
+ path: ["scope"]
1787
+ }
1788
+ ];
1789
+ var withDerivedScope = (data) => ({
1790
+ ...data,
1791
+ scope: data.scope ?? (data.contracts.length > 0 ? SCOPE_CONTRACT : data.handles.length > 0 ? SCOPE_HANDLES : SCOPE_GLOBAL)
1792
+ });
1793
+ var zACPWithDefaults = zod.z.object({
1794
+ name: zod.z.string().optional().default("Unnamed ACP"),
1890
1795
  type: zod.z.enum(["self", "sharing", "recipient"]),
1891
1796
  issuer: addressNotZeroSchema,
1892
1797
  expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1893
1798
  recipient: addressSchema.optional().default(viem.zeroAddress),
1894
- validatorId: zod.z.int().optional().default(0),
1895
- validatorContract: addressSchema.optional().default(viem.zeroAddress),
1799
+ revokerData: zod.z.int().optional().default(0),
1800
+ revokerContract: addressSchema.optional().default(viem.zeroAddress),
1801
+ scope: zod.z.int().min(0).max(2).optional().default(0),
1802
+ contracts: contractsSchema,
1803
+ handles: handlesSchema,
1896
1804
  issuerSignature: bytesSchema.optional().default("0x"),
1897
1805
  recipientSignature: bytesSchema.optional().default("0x")
1898
1806
  });
1899
- var zPermitWithSealingPair = zPermitWithDefaults.extend({
1900
- sealingPair: SerializedSealingPair.optional()
1807
+ var zACPWithSealingKeys = zACPWithDefaults.extend({
1808
+ /** X25519 private key, 0x-prefixed 32-byte hex; never leaves the client */
1809
+ sealingPrivateKey: zod.z.string().regex(/^0x[0-9a-fA-F]{64}$/, "Invalid sealing private key").optional(),
1810
+ sealingKey: zod.z.string().regex(/^0x[0-9a-fA-F]{64}$/, "Invalid sealing key").optional()
1901
1811
  });
1902
1812
  var ExternalValidatorRefinement = [
1903
- (data) => data.validatorId !== 0 && data.validatorContract !== viem.zeroAddress || data.validatorId === 0 && data.validatorContract === viem.zeroAddress,
1813
+ (data) => data.revokerData !== 0 && data.revokerContract !== viem.zeroAddress || data.revokerData === 0 && data.revokerContract === viem.zeroAddress,
1904
1814
  {
1905
- error: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
1906
- path: ["validatorId", "validatorContract"]
1815
+ error: "ACP external revoker :: revokerData and revokerContract must either both be set or both be unset.",
1816
+ path: ["revokerData", "revokerContract"]
1907
1817
  }
1908
1818
  ];
1909
1819
  var RecipientRefinement = [
1910
1820
  (data) => data.issuer !== data.recipient,
1911
1821
  {
1912
- error: "Sharing permit :: issuer and recipient must not be the same",
1822
+ error: "Sharing acp :: issuer and recipient must not be the same",
1913
1823
  path: ["issuer", "recipient"]
1914
1824
  }
1915
1825
  ];
1916
- var SelfPermitOptionsValidator = zod.z.object({
1826
+ var SelfACPOptionsValidator = zod.z.object({
1917
1827
  type: zod.z.literal("self").optional().default("self"),
1918
1828
  issuer: addressNotZeroSchema,
1919
- name: zod.z.string().optional().default("Unnamed Permit"),
1829
+ name: zod.z.string().optional().default("Unnamed ACP"),
1920
1830
  expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1921
1831
  recipient: addressSchema.optional().default(viem.zeroAddress),
1922
- validatorId: zod.z.int().optional().default(0),
1923
- validatorContract: addressSchema.optional().default(viem.zeroAddress),
1832
+ revokerData: zod.z.int().optional().default(0),
1833
+ revokerContract: addressSchema.optional().default(viem.zeroAddress),
1834
+ scope: zod.z.int().min(0).max(2).optional(),
1835
+ contracts: contractsSchema,
1836
+ handles: handlesSchema,
1924
1837
  issuerSignature: bytesSchema.optional().default("0x"),
1925
1838
  recipientSignature: bytesSchema.optional().default("0x")
1926
- }).refine(...ExternalValidatorRefinement);
1927
- var SelfPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "self", {
1839
+ }).refine(...ExternalValidatorRefinement).transform(withDerivedScope).refine(...ScopeConsistencyRefinement);
1840
+ var SelfACPValidator = zACPWithSealingKeys.refine((data) => data.type === "self", {
1928
1841
  error: "Type must be 'self'"
1929
1842
  }).refine((data) => data.recipient === viem.zeroAddress, {
1930
1843
  error: "Recipient must be zeroAddress"
@@ -1933,18 +1846,21 @@ var SelfPermitValidator = zPermitWithSealingPair.refine((data) => data.type ===
1933
1846
  }).refine((data) => data.recipientSignature === "0x", {
1934
1847
  error: "RecipientSignature must be empty"
1935
1848
  }).refine(...ExternalValidatorRefinement);
1936
- var SharingPermitOptionsValidator = zod.z.object({
1849
+ var SharingACPOptionsValidator = zod.z.object({
1937
1850
  type: zod.z.literal("sharing").optional().default("sharing"),
1938
1851
  issuer: addressNotZeroSchema,
1939
1852
  recipient: addressNotZeroSchema,
1940
- name: zod.z.string().optional().default("Unnamed Permit"),
1853
+ name: zod.z.string().optional().default("Unnamed ACP"),
1941
1854
  expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
1942
- validatorId: zod.z.int().optional().default(0),
1943
- validatorContract: addressSchema.optional().default(viem.zeroAddress),
1855
+ revokerData: zod.z.int().optional().default(0),
1856
+ revokerContract: addressSchema.optional().default(viem.zeroAddress),
1857
+ scope: zod.z.int().min(0).max(2).optional(),
1858
+ contracts: contractsSchema,
1859
+ handles: handlesSchema,
1944
1860
  issuerSignature: bytesSchema.optional().default("0x"),
1945
1861
  recipientSignature: bytesSchema.optional().default("0x")
1946
- }).refine(...RecipientRefinement).refine(...ExternalValidatorRefinement);
1947
- var SharingPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "sharing", {
1862
+ }).refine(...RecipientRefinement).refine(...ExternalValidatorRefinement).transform(withDerivedScope).refine(...ScopeConsistencyRefinement);
1863
+ var SharingACPValidator = zACPWithSealingKeys.refine((data) => data.type === "sharing", {
1948
1864
  error: "Type must be 'sharing'"
1949
1865
  }).refine((data) => data.recipient !== viem.zeroAddress, {
1950
1866
  error: "Recipient must not be zeroAddress"
@@ -1953,18 +1869,21 @@ var SharingPermitValidator = zPermitWithSealingPair.refine((data) => data.type =
1953
1869
  }).refine((data) => data.recipientSignature === "0x", {
1954
1870
  error: "RecipientSignature must be empty"
1955
1871
  }).refine(...ExternalValidatorRefinement);
1956
- var ImportPermitOptionsValidator = zod.z.object({
1872
+ var ImportACPOptionsValidator = zod.z.object({
1957
1873
  type: zod.z.literal("recipient").optional().default("recipient"),
1958
1874
  issuer: addressNotZeroSchema,
1959
1875
  recipient: addressNotZeroSchema,
1960
- name: zod.z.string().optional().default("Unnamed Permit"),
1876
+ name: zod.z.string().optional().default("Unnamed ACP"),
1961
1877
  expiration: zod.z.int(),
1962
- validatorId: zod.z.int().optional().default(0),
1963
- validatorContract: addressSchema.optional().default(viem.zeroAddress),
1878
+ revokerData: zod.z.int().optional().default(0),
1879
+ revokerContract: addressSchema.optional().default(viem.zeroAddress),
1880
+ scope: zod.z.int().min(0).max(2).optional(),
1881
+ contracts: contractsSchema,
1882
+ handles: handlesSchema,
1964
1883
  issuerSignature: bytesNotEmptySchema,
1965
1884
  recipientSignature: bytesSchema.optional().default("0x")
1966
- }).refine(...ExternalValidatorRefinement);
1967
- var ImportPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "recipient", {
1885
+ }).refine(...ExternalValidatorRefinement).transform(withDerivedScope).refine(...ScopeConsistencyRefinement);
1886
+ var ImportACPValidator = zACPWithSealingKeys.refine((data) => data.type === "recipient", {
1968
1887
  error: "Type must be 'recipient'"
1969
1888
  }).refine((data) => data.recipient !== viem.zeroAddress, {
1970
1889
  error: "Recipient must not be zeroAddress"
@@ -1980,116 +1899,125 @@ var safeParseAndThrowFormatted = (schema, data, message) => {
1980
1899
  }
1981
1900
  return result.data;
1982
1901
  };
1983
- var validateSelfPermitOptions = (options) => {
1984
- return safeParseAndThrowFormatted(SelfPermitOptionsValidator, options, "Invalid self permit options");
1902
+ var validateSelfACPOptions = (options) => {
1903
+ return safeParseAndThrowFormatted(SelfACPOptionsValidator, options, "Invalid self acp options");
1985
1904
  };
1986
- var validateSharingPermitOptions = (options) => {
1987
- return safeParseAndThrowFormatted(SharingPermitOptionsValidator, options, "Invalid sharing permit options");
1905
+ var validateSharingACPOptions = (options) => {
1906
+ return safeParseAndThrowFormatted(SharingACPOptionsValidator, options, "Invalid sharing acp options");
1988
1907
  };
1989
- var validateImportPermitOptions = (options) => {
1990
- return safeParseAndThrowFormatted(ImportPermitOptionsValidator, options, "Invalid import permit options");
1908
+ var validateImportACPOptions = (options) => {
1909
+ return safeParseAndThrowFormatted(ImportACPOptionsValidator, options, "Invalid import acp options");
1991
1910
  };
1992
- var validateSelfPermit = (permit) => {
1993
- return safeParseAndThrowFormatted(SelfPermitValidator, permit, "Invalid self permit");
1911
+ var validateSelfACP = (acp) => {
1912
+ return safeParseAndThrowFormatted(SelfACPValidator, acp, "Invalid self acp");
1994
1913
  };
1995
- var validateSharingPermit = (permit) => {
1996
- return safeParseAndThrowFormatted(SharingPermitValidator, permit, "Invalid sharing permit");
1914
+ var validateSharingACP = (acp) => {
1915
+ return safeParseAndThrowFormatted(SharingACPValidator, acp, "Invalid sharing acp");
1997
1916
  };
1998
- var validateImportPermit = (permit) => {
1999
- return safeParseAndThrowFormatted(ImportPermitValidator, permit, "Invalid import permit");
1917
+ var validateImportACP = (acp) => {
1918
+ return safeParseAndThrowFormatted(ImportACPValidator, acp, "Invalid import acp");
2000
1919
  };
2001
1920
  var ValidationUtils = {
2002
1921
  /**
2003
- * Check if permit is expired
1922
+ * Check if acp is expired
2004
1923
  */
2005
- isExpired: (permit) => {
2006
- return permit.expiration < Math.floor(Date.now() / 1e3);
1924
+ isExpired: (acp) => {
1925
+ return acp.expiration < Math.floor(Date.now() / 1e3);
2007
1926
  },
2008
1927
  /**
2009
- * Check if permit is signed by the active party
1928
+ * Check if acp is signed by the active party
2010
1929
  */
2011
- isSigned: (permit) => {
2012
- if (permit.type === "self" || permit.type === "sharing") {
2013
- return permit.issuerSignature !== "0x";
1930
+ isSigned: (acp) => {
1931
+ if (acp.type === "self" || acp.type === "sharing") {
1932
+ return acp.issuerSignature !== "0x";
2014
1933
  }
2015
- if (permit.type === "recipient") {
2016
- return permit.recipientSignature !== "0x";
1934
+ if (acp.type === "recipient") {
1935
+ return acp.recipientSignature !== "0x";
2017
1936
  }
2018
1937
  return false;
2019
1938
  },
2020
1939
  /**
2021
- * Checks that a permit is signed and not expired.
1940
+ * Checks that an ACP is signed and not expired.
2022
1941
  */
2023
- isSignedAndNotExpired: (permit) => {
2024
- if (ValidationUtils.isExpired(permit)) {
1942
+ isSignedAndNotExpired: (acp) => {
1943
+ if (ValidationUtils.isExpired(acp)) {
2025
1944
  return { valid: false, error: "expired" };
2026
1945
  }
2027
- if (!ValidationUtils.isSigned(permit)) {
1946
+ if (!ValidationUtils.isSigned(acp)) {
2028
1947
  return { valid: false, error: "not-signed" };
2029
1948
  }
2030
1949
  return { valid: true, error: null };
2031
1950
  },
2032
1951
  /**
2033
- * Asserts that a permit is signed and not expired.
1952
+ * Asserts that an ACP is signed and not expired.
2034
1953
  *
2035
1954
  * Throws `Error` with message:
2036
- * - `Permit is expired`
2037
- * - `Permit is not signed`
1955
+ * - `ACP is expired`
1956
+ * - `ACP is not signed`
2038
1957
  */
2039
- assertSignedAndNotExpired: (permit) => {
2040
- const result = ValidationUtils.isSignedAndNotExpired(permit);
1958
+ assertSignedAndNotExpired: (acp) => {
1959
+ const result = ValidationUtils.isSignedAndNotExpired(acp);
2041
1960
  if (result.valid)
2042
1961
  return;
2043
1962
  if (result.error === "expired") {
2044
- throw new Error("Permit is expired");
1963
+ throw new Error("ACP is expired");
2045
1964
  }
2046
1965
  if (result.error === "not-signed") {
2047
- throw new Error("Permit is not signed");
1966
+ throw new Error("ACP is not signed");
2048
1967
  }
2049
- throw new Error("Permit is invalid");
1968
+ throw new Error("ACP is invalid");
2050
1969
  },
2051
- isValid: (permit) => {
2052
- const schema = permit.type === "self" ? SelfPermitValidator : permit.type === "sharing" ? SharingPermitValidator : permit.type === "recipient" ? ImportPermitValidator : null;
1970
+ isValid: (acp) => {
1971
+ const schema = acp.type === "self" ? SelfACPValidator : acp.type === "sharing" ? SharingACPValidator : acp.type === "recipient" ? ImportACPValidator : null;
2053
1972
  if (schema == null)
2054
1973
  return { valid: false, error: "invalid-schema" };
2055
- const schemaResult = schema.safeParse(permit);
1974
+ const schemaResult = schema.safeParse(acp);
2056
1975
  if (!schemaResult.success)
2057
1976
  return { valid: false, error: "invalid-schema" };
2058
- return ValidationUtils.isSignedAndNotExpired(permit);
1977
+ return ValidationUtils.isSignedAndNotExpired(acp);
2059
1978
  }
2060
1979
  };
2061
1980
 
2062
- // permits/signature.ts
2063
- var PermitSignatureAllFields = [
1981
+ // acps/signature.ts
1982
+ var ACPSignatureAllFields = [
2064
1983
  { name: "issuer", type: "address" },
2065
1984
  { name: "expiration", type: "uint64" },
2066
1985
  { name: "recipient", type: "address" },
2067
- { name: "validatorId", type: "uint256" },
2068
- { name: "validatorContract", type: "address" },
1986
+ { name: "revokerData", type: "uint256" },
1987
+ { name: "revokerContract", type: "address" },
1988
+ { name: "scope", type: "uint8" },
1989
+ { name: "contracts", type: "address[]" },
1990
+ { name: "handles", type: "bytes32[]" },
2069
1991
  { name: "sealingKey", type: "bytes32" },
2070
1992
  { name: "issuerSignature", type: "bytes" }
2071
1993
  ];
2072
1994
  var SignatureTypes = {
2073
- PermissionedV2IssuerSelf: [
1995
+ ACPIssuerSelf: [
2074
1996
  "issuer",
2075
1997
  "expiration",
2076
1998
  "recipient",
2077
- "validatorId",
2078
- "validatorContract",
1999
+ "revokerData",
2000
+ "revokerContract",
2001
+ "scope",
2002
+ "contracts",
2003
+ "handles",
2079
2004
  "sealingKey"
2080
2005
  ],
2081
- PermissionedV2IssuerShared: [
2006
+ ACPIssuerShared: [
2082
2007
  "issuer",
2083
2008
  "expiration",
2084
2009
  "recipient",
2085
- "validatorId",
2086
- "validatorContract"
2010
+ "revokerData",
2011
+ "revokerContract",
2012
+ "scope",
2013
+ "contracts",
2014
+ "handles"
2087
2015
  ],
2088
- PermissionedV2Recipient: ["sealingKey", "issuerSignature"]
2016
+ ACPRecipient: ["sealingKey", "issuerSignature"]
2089
2017
  };
2090
2018
  var getSignatureTypesAndMessage = (primaryType, fields, values) => {
2091
2019
  const types = {
2092
- [primaryType]: PermitSignatureAllFields.filter((fieldType) => fields.includes(fieldType.name))
2020
+ [primaryType]: ACPSignatureAllFields.filter((fieldType) => fields.includes(fieldType.name))
2093
2021
  };
2094
2022
  const message = {};
2095
2023
  fields.forEach((field) => {
@@ -2101,22 +2029,22 @@ var getSignatureTypesAndMessage = (primaryType, fields, values) => {
2101
2029
  };
2102
2030
  var SignatureUtils = {
2103
2031
  /**
2104
- * Get signature parameters for a permit
2032
+ * Get signature parameters for an ACP
2105
2033
  */
2106
- getSignatureParams: (permit, primaryType) => {
2107
- return getSignatureTypesAndMessage(primaryType, SignatureTypes[primaryType], permit);
2034
+ getSignatureParams: (acp, primaryType) => {
2035
+ return getSignatureTypesAndMessage(primaryType, SignatureTypes[primaryType], acp);
2108
2036
  },
2109
2037
  /**
2110
- * Determine the required signature type based on permit type
2038
+ * Determine the required signature type based on acp type
2111
2039
  */
2112
- getPrimaryType: (permitType) => {
2113
- if (permitType === "self")
2114
- return "PermissionedV2IssuerSelf";
2115
- if (permitType === "sharing")
2116
- return "PermissionedV2IssuerShared";
2117
- if (permitType === "recipient")
2118
- return "PermissionedV2Recipient";
2119
- throw new Error(`Unknown permit type: ${permitType}`);
2040
+ getPrimaryType: (acpType) => {
2041
+ if (acpType === "self")
2042
+ return "ACPIssuerSelf";
2043
+ if (acpType === "sharing")
2044
+ return "ACPIssuerShared";
2045
+ if (acpType === "recipient")
2046
+ return "ACPRecipient";
2047
+ throw new Error(`Unknown acp type: ${acpType}`);
2120
2048
  }
2121
2049
  };
2122
2050
  var getAclAddress = async (publicClient) => {
@@ -2138,6 +2066,11 @@ var getAclEIP712Domain = async (publicClient) => {
2138
2066
  functionName: "eip712Domain"
2139
2067
  });
2140
2068
  const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
2069
+ if (version !== "2") {
2070
+ throw new Error(
2071
+ `Chain ${chainId}'s ACL serves EIP-712 domain version "${version}" \u2014 this SDK requires the upgraded (ACP-era) ACL, which signs as version "2". Pre-upgrade (V2 Permission) chains are not supported.`
2072
+ );
2073
+ }
2141
2074
  return {
2142
2075
  name,
2143
2076
  version,
@@ -2145,23 +2078,26 @@ var getAclEIP712Domain = async (publicClient) => {
2145
2078
  verifyingContract
2146
2079
  };
2147
2080
  };
2148
- var checkPermitValidityOnChain = async (permission, publicClient) => {
2081
+ var checkACPValidityOnChain = async (acp, publicClient) => {
2149
2082
  const aclAddress = await getAclAddress(publicClient);
2150
2083
  try {
2151
2084
  await publicClient.simulateContract({
2152
2085
  address: aclAddress,
2153
- abi: checkPermitValidityAbi,
2154
- functionName: "checkPermitValidity",
2086
+ abi: checkACPValidityAbi,
2087
+ functionName: "checkPermissionValidity",
2155
2088
  args: [
2156
2089
  {
2157
- issuer: permission.issuer,
2158
- expiration: BigInt(permission.expiration),
2159
- recipient: permission.recipient,
2160
- validatorId: BigInt(permission.validatorId),
2161
- validatorContract: permission.validatorContract,
2162
- sealingKey: permission.sealingKey,
2163
- issuerSignature: permission.issuerSignature,
2164
- recipientSignature: permission.recipientSignature
2090
+ issuer: acp.issuer,
2091
+ expiration: BigInt(acp.expiration),
2092
+ recipient: acp.recipient,
2093
+ revokerData: BigInt(acp.revokerData),
2094
+ revokerContract: acp.revokerContract,
2095
+ scope: acp.scope,
2096
+ contracts: acp.contracts,
2097
+ handles: acp.handles,
2098
+ sealingKey: acp.sealingKey,
2099
+ issuerSignature: acp.issuerSignature,
2100
+ recipientSignature: acp.recipientSignature
2165
2101
  }
2166
2102
  ]
2167
2103
  });
@@ -2174,14 +2110,14 @@ var checkPermitValidityOnChain = async (permission, publicClient) => {
2174
2110
  throw new Error(errorName);
2175
2111
  }
2176
2112
  }
2177
- const customErrorName = extractCustomErrorFromDetails(err, checkPermitValidityAbi);
2113
+ const customErrorName = extractCustomErrorFromDetails(err, checkACPValidityAbi);
2178
2114
  if (customErrorName) {
2179
2115
  throw new Error(customErrorName);
2180
2116
  }
2181
2117
  const hhDetailsData = extractReturnData(err);
2182
2118
  if (hhDetailsData != null) {
2183
2119
  const decoded = viem.decodeErrorResult({
2184
- abi: checkPermitValidityAbi,
2120
+ abi: checkACPValidityAbi,
2185
2121
  data: hhDetailsData
2186
2122
  });
2187
2123
  throw new Error(decoded.errorName);
@@ -2209,15 +2145,15 @@ function extractReturnData(err) {
2209
2145
  const s = anyErr?.details ?? anyErr?.cause?.details ?? anyErr?.shortMessage ?? anyErr?.message ?? String(err);
2210
2146
  return s.match(/return data:\s*(0x[a-fA-F0-9]+)/)?.[1];
2211
2147
  }
2212
- var checkPermitValidityAbi = [
2148
+ var checkACPValidityAbi = [
2213
2149
  {
2214
2150
  type: "function",
2215
- name: "checkPermitValidity",
2151
+ name: "checkPermissionValidity",
2216
2152
  inputs: [
2217
2153
  {
2218
- name: "permission",
2154
+ name: "acp",
2219
2155
  type: "tuple",
2220
- internalType: "struct Permission",
2156
+ internalType: "struct ACP",
2221
2157
  components: [
2222
2158
  {
2223
2159
  name: "issuer",
@@ -2235,15 +2171,30 @@ var checkPermitValidityAbi = [
2235
2171
  internalType: "address"
2236
2172
  },
2237
2173
  {
2238
- name: "validatorId",
2174
+ name: "revokerData",
2239
2175
  type: "uint256",
2240
2176
  internalType: "uint256"
2241
2177
  },
2242
2178
  {
2243
- name: "validatorContract",
2179
+ name: "revokerContract",
2244
2180
  type: "address",
2245
2181
  internalType: "address"
2246
2182
  },
2183
+ {
2184
+ name: "scope",
2185
+ type: "uint8",
2186
+ internalType: "uint8"
2187
+ },
2188
+ {
2189
+ name: "contracts",
2190
+ type: "address[]",
2191
+ internalType: "address[]"
2192
+ },
2193
+ {
2194
+ name: "handles",
2195
+ type: "bytes32[]",
2196
+ internalType: "bytes32[]"
2197
+ },
2247
2198
  {
2248
2199
  name: "sealingKey",
2249
2200
  type: "bytes32",
@@ -2293,38 +2244,40 @@ var checkPermitValidityAbi = [
2293
2244
  }
2294
2245
  ];
2295
2246
 
2296
- // permits/permit.ts
2297
- var PermitUtils = {
2247
+ // acps/acp.ts
2248
+ var ACPUtils = {
2298
2249
  /**
2299
- * Create a self permit for personal use
2250
+ * Create a self acp for personal use
2300
2251
  */
2301
2252
  createSelf: (options) => {
2302
- const validation = validateSelfPermitOptions(options);
2253
+ const validation = validateSelfACPOptions(options);
2303
2254
  const sealingPair = GenerateSealingKey();
2304
- const permit = {
2305
- hash: PermitUtils.getHash(validation),
2255
+ const acp = {
2256
+ hash: ACPUtils.getHash(validation),
2306
2257
  ...validation,
2307
- sealingPair,
2258
+ sealingPrivateKey: sealingPair.privateKey,
2259
+ sealingKey: sealingPair.publicKey,
2308
2260
  _signedDomain: void 0
2309
2261
  };
2310
- return permit;
2262
+ return acp;
2311
2263
  },
2312
2264
  /**
2313
- * Create a sharing permit to be shared with another user
2265
+ * Create a sharing acp to be shared with another user
2314
2266
  */
2315
2267
  createSharing: (options) => {
2316
- const validation = validateSharingPermitOptions(options);
2268
+ const validation = validateSharingACPOptions(options);
2317
2269
  const sealingPair = GenerateSealingKey();
2318
- const permit = {
2319
- hash: PermitUtils.getHash(validation),
2270
+ const acp = {
2271
+ hash: ACPUtils.getHash(validation),
2320
2272
  ...validation,
2321
- sealingPair,
2273
+ sealingPrivateKey: sealingPair.privateKey,
2274
+ sealingKey: sealingPair.publicKey,
2322
2275
  _signedDomain: void 0
2323
2276
  };
2324
- return permit;
2277
+ return acp;
2325
2278
  },
2326
2279
  /**
2327
- * Import a shared permit from various input formats
2280
+ * Import a shared acp from various input formats
2328
2281
  */
2329
2282
  importShared: (options) => {
2330
2283
  let parsedOptions;
@@ -2337,33 +2290,34 @@ var PermitUtils = {
2337
2290
  } else if (typeof options === "object" && options !== null) {
2338
2291
  parsedOptions = options;
2339
2292
  } else {
2340
- throw new Error("Invalid input type, expected ImportSharedPermitOptions, object, or string");
2293
+ throw new Error("Invalid input type, expected ImportSharedACPOptions, object, or string");
2341
2294
  }
2342
2295
  if (parsedOptions.type != null && parsedOptions.type !== "sharing") {
2343
- throw new Error(`Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
2296
+ throw new Error(`Invalid acp type <${parsedOptions.type}>, must be "sharing"`);
2344
2297
  }
2345
- const validation = validateImportPermitOptions({ ...parsedOptions, type: "recipient" });
2298
+ const validation = validateImportACPOptions({ ...parsedOptions, type: "recipient" });
2346
2299
  const sealingPair = GenerateSealingKey();
2347
- const permit = {
2348
- hash: PermitUtils.getHash(validation),
2300
+ const acp = {
2301
+ hash: ACPUtils.getHash(validation),
2349
2302
  ...validation,
2350
- sealingPair,
2303
+ sealingPrivateKey: sealingPair.privateKey,
2304
+ sealingKey: sealingPair.publicKey,
2351
2305
  _signedDomain: void 0
2352
2306
  };
2353
- return permit;
2307
+ return acp;
2354
2308
  },
2355
2309
  /**
2356
- * Sign a permit with the provided wallet client
2310
+ * Sign an ACP with the provided wallet client
2357
2311
  */
2358
- sign: async (permit, publicClient, walletClient) => {
2312
+ sign: async (acp, publicClient, walletClient) => {
2359
2313
  if (walletClient == null || walletClient.account == null) {
2360
2314
  throw new Error(
2361
- "Missing walletClient, you must pass in a `walletClient` for the connected user to create a permit signature"
2315
+ "Missing walletClient, you must pass in a `walletClient` for the connected user to create an ACP signature"
2362
2316
  );
2363
2317
  }
2364
- const primaryType = SignatureUtils.getPrimaryType(permit.type);
2318
+ const primaryType = SignatureUtils.getPrimaryType(acp.type);
2365
2319
  const domain = await getAclEIP712Domain(publicClient);
2366
- const { types, message } = SignatureUtils.getSignatureParams(PermitUtils.getPermission(permit, true), primaryType);
2320
+ const { types, message } = SignatureUtils.getSignatureParams(ACPUtils.getPublic(acp, true), primaryType);
2367
2321
  const signature = await walletClient.signTypedData({
2368
2322
  domain,
2369
2323
  types,
@@ -2371,190 +2325,209 @@ var PermitUtils = {
2371
2325
  message,
2372
2326
  account: walletClient.account
2373
2327
  });
2374
- let updatedPermit;
2375
- if (permit.type === "self" || permit.type === "sharing") {
2376
- updatedPermit = {
2377
- ...permit,
2328
+ let updatedACP;
2329
+ if (acp.type === "self" || acp.type === "sharing") {
2330
+ updatedACP = {
2331
+ ...acp,
2378
2332
  issuerSignature: signature,
2379
2333
  _signedDomain: domain
2380
2334
  };
2381
2335
  } else {
2382
- updatedPermit = {
2383
- ...permit,
2336
+ updatedACP = {
2337
+ ...acp,
2384
2338
  recipientSignature: signature,
2385
2339
  _signedDomain: domain
2386
2340
  };
2387
2341
  }
2388
- return updatedPermit;
2342
+ return updatedACP;
2389
2343
  },
2390
2344
  /**
2391
- * Create and sign a self permit in one operation
2345
+ * Create and sign a self acp in one operation
2392
2346
  */
2393
2347
  createSelfAndSign: async (options, publicClient, walletClient) => {
2394
- const permit = PermitUtils.createSelf(options);
2395
- return PermitUtils.sign(permit, publicClient, walletClient);
2348
+ const acp = ACPUtils.createSelf(options);
2349
+ return ACPUtils.sign(acp, publicClient, walletClient);
2396
2350
  },
2397
2351
  /**
2398
- * Create and sign a sharing permit in one operation
2352
+ * Create and sign a sharing acp in one operation
2399
2353
  */
2400
2354
  createSharingAndSign: async (options, publicClient, walletClient) => {
2401
- const permit = PermitUtils.createSharing(options);
2402
- return PermitUtils.sign(permit, publicClient, walletClient);
2355
+ const acp = ACPUtils.createSharing(options);
2356
+ return ACPUtils.sign(acp, publicClient, walletClient);
2403
2357
  },
2404
2358
  /**
2405
- * Import and sign a shared permit in one operation from various input formats
2359
+ * Import and sign a shared acp in one operation from various input formats
2406
2360
  */
2407
2361
  importSharedAndSign: async (options, publicClient, walletClient) => {
2408
- const permit = PermitUtils.importShared(options);
2409
- return PermitUtils.sign(permit, publicClient, walletClient);
2362
+ const acp = ACPUtils.importShared(options);
2363
+ return ACPUtils.sign(acp, publicClient, walletClient);
2410
2364
  },
2411
2365
  /**
2412
- * Deserialize a permit from serialized data
2366
+ * Deserialize an ACP from serialized data
2413
2367
  */
2414
2368
  deserialize: (data) => {
2415
- return {
2416
- ...data,
2417
- sealingPair: SealingKey.deserialize(data.sealingPair.privateKey, data.sealingPair.publicKey)
2418
- };
2369
+ return { ...data };
2419
2370
  },
2420
2371
  /**
2421
- * Serialize a permit for storage
2372
+ * Serialize an ACP for storage
2422
2373
  */
2423
- serialize: (permit) => {
2374
+ serialize: (acp) => {
2424
2375
  return {
2425
- hash: permit.hash,
2426
- name: permit.name,
2427
- type: permit.type,
2428
- issuer: permit.issuer,
2429
- expiration: permit.expiration,
2430
- recipient: permit.recipient,
2431
- validatorId: permit.validatorId,
2432
- validatorContract: permit.validatorContract,
2433
- issuerSignature: permit.issuerSignature,
2434
- recipientSignature: permit.recipientSignature,
2435
- _signedDomain: permit._signedDomain,
2436
- sealingPair: permit.sealingPair.serialize()
2376
+ hash: acp.hash,
2377
+ name: acp.name,
2378
+ type: acp.type,
2379
+ issuer: acp.issuer,
2380
+ expiration: acp.expiration,
2381
+ recipient: acp.recipient,
2382
+ revokerData: acp.revokerData,
2383
+ revokerContract: acp.revokerContract,
2384
+ scope: acp.scope,
2385
+ contracts: acp.contracts,
2386
+ handles: acp.handles,
2387
+ sealingKey: acp.sealingKey,
2388
+ issuerSignature: acp.issuerSignature,
2389
+ recipientSignature: acp.recipientSignature,
2390
+ _signedDomain: acp._signedDomain,
2391
+ sealingPrivateKey: acp.sealingPrivateKey
2437
2392
  };
2438
2393
  },
2439
2394
  /**
2440
- * Validate a permit (schema-level validation)
2395
+ * Validate an ACP (schema-level validation)
2441
2396
  */
2442
- validateSchema: (permit) => {
2443
- if (permit.type === "self") {
2444
- return validateSelfPermit(permit);
2445
- } else if (permit.type === "sharing") {
2446
- return validateSharingPermit(permit);
2447
- } else if (permit.type === "recipient") {
2448
- return validateImportPermit(permit);
2397
+ validateSchema: (acp) => {
2398
+ if (acp.type === "self") {
2399
+ return validateSelfACP(acp);
2400
+ } else if (acp.type === "sharing") {
2401
+ return validateSharingACP(acp);
2402
+ } else if (acp.type === "recipient") {
2403
+ return validateImportACP(acp);
2449
2404
  } else {
2450
- throw new Error("Invalid permit type");
2405
+ throw new Error("Invalid ACP type");
2451
2406
  }
2452
2407
  },
2453
2408
  /**
2454
- * Validate a permit (holistic validation).
2409
+ * Validate an ACP (holistic validation).
2455
2410
  *
2456
2411
  * This validates:
2457
- * - Permit schema (shape + invariants)
2458
- * - Permit is signed
2459
- * - Permit is not expired
2412
+ * - ACP schema (shape + invariants)
2413
+ * - ACP is signed
2414
+ * - ACP is not expired
2460
2415
  *
2461
- * For schema-only validation, use `validateSchema(permit)`.
2416
+ * For schema-only validation, use `validateSchema(acp)`.
2462
2417
  */
2463
- validate: (permit) => {
2464
- const validated = PermitUtils.validateSchema(permit);
2418
+ validate: (acp) => {
2419
+ const validated = ACPUtils.validateSchema(acp);
2465
2420
  ValidationUtils.assertSignedAndNotExpired(validated);
2466
2421
  return validated;
2467
2422
  },
2468
2423
  /**
2469
- * Get the permission object from a permit (for use in contracts)
2424
+ * Get the public component of an ACP the signed struct sent on-chain / to the decryption backend.
2425
+ * Strips the private component (hash, name, type, sealing pair).
2470
2426
  */
2471
- getPermission: (permit, skipValidation = false) => {
2427
+ getPublic: (acp, skipValidation = false) => {
2472
2428
  if (!skipValidation) {
2473
- PermitUtils.validateSchema(permit);
2429
+ ACPUtils.validateSchema(acp);
2474
2430
  }
2475
2431
  return {
2476
- issuer: permit.issuer,
2477
- expiration: permit.expiration,
2478
- recipient: permit.recipient,
2479
- validatorId: permit.validatorId,
2480
- validatorContract: permit.validatorContract,
2481
- sealingKey: `0x${permit.sealingPair.publicKey}`,
2482
- issuerSignature: permit.issuerSignature,
2483
- recipientSignature: permit.recipientSignature
2432
+ issuer: acp.issuer,
2433
+ expiration: acp.expiration,
2434
+ recipient: acp.recipient,
2435
+ revokerData: acp.revokerData,
2436
+ revokerContract: acp.revokerContract,
2437
+ scope: acp.scope,
2438
+ contracts: acp.contracts,
2439
+ handles: acp.handles,
2440
+ sealingKey: acp.sealingKey,
2441
+ issuerSignature: acp.issuerSignature,
2442
+ recipientSignature: acp.recipientSignature
2484
2443
  };
2485
2444
  },
2486
2445
  /**
2487
- * Get a stable hash for the permit (used as key in storage)
2446
+ * Get a stable hash for the acp (used as key in storage)
2488
2447
  */
2489
- getHash: (permit) => {
2448
+ getHash: (acp) => {
2490
2449
  const data = JSON.stringify({
2491
- type: permit.type,
2492
- issuer: permit.issuer,
2493
- expiration: permit.expiration,
2494
- recipient: permit.recipient,
2495
- validatorId: permit.validatorId,
2496
- validatorContract: permit.validatorContract
2450
+ type: acp.type,
2451
+ issuer: acp.issuer,
2452
+ expiration: acp.expiration,
2453
+ recipient: acp.recipient,
2454
+ revokerData: acp.revokerData,
2455
+ revokerContract: acp.revokerContract,
2456
+ scope: acp.scope,
2457
+ contracts: acp.contracts,
2458
+ handles: acp.handles
2497
2459
  });
2498
2460
  return viem.keccak256(viem.toHex(data));
2499
2461
  },
2500
2462
  /**
2501
- * Export permit data for sharing (removes sensitive fields)
2463
+ * Export acp data for sharing (strips the private component).
2464
+ * Fixed `SharedACP` shape — every field always present, aligned with
2465
+ * `ACPPublic` and the on-chain sharing payload.
2502
2466
  */
2503
- export: (permit) => {
2504
- const cleanedPermit = {
2505
- name: permit.name,
2506
- type: permit.type,
2507
- issuer: permit.issuer,
2508
- expiration: permit.expiration
2467
+ export: (acp) => {
2468
+ if (acp.type !== "sharing") {
2469
+ throw new Error(
2470
+ `Cannot export a '${acp.type}' ACP \u2014 only 'sharing' ACPs are exportable. The export includes the issuer signature.`
2471
+ );
2472
+ }
2473
+ if (acp.issuerSignature === "0x") {
2474
+ throw new Error(
2475
+ "Cannot export an unsigned sharing ACP \u2014 sign it first (the recipient needs the issuer signature)."
2476
+ );
2477
+ }
2478
+ const shared = {
2479
+ name: acp.name,
2480
+ type: acp.type,
2481
+ issuer: acp.issuer,
2482
+ expiration: acp.expiration,
2483
+ recipient: acp.recipient,
2484
+ revokerData: acp.revokerData,
2485
+ revokerContract: acp.revokerContract,
2486
+ scope: acp.scope,
2487
+ contracts: acp.contracts,
2488
+ handles: acp.handles,
2489
+ issuerSignature: acp.issuerSignature
2509
2490
  };
2510
- if (permit.recipient !== viem.zeroAddress)
2511
- cleanedPermit.recipient = permit.recipient;
2512
- if (permit.validatorId !== 0)
2513
- cleanedPermit.validatorId = permit.validatorId;
2514
- if (permit.validatorContract !== viem.zeroAddress)
2515
- cleanedPermit.validatorContract = permit.validatorContract;
2516
- if (permit.type === "sharing" && permit.issuerSignature !== "0x")
2517
- cleanedPermit.issuerSignature = permit.issuerSignature;
2518
- return JSON.stringify(cleanedPermit, void 0, 2);
2491
+ return JSON.stringify(shared, void 0, 2);
2519
2492
  },
2520
2493
  /**
2521
- * Unseal encrypted data using the permit's sealing key
2494
+ * Unseal encrypted data using the acp's sealing key
2522
2495
  */
2523
- unseal: (permit, ciphertext) => {
2524
- return permit.sealingPair.unseal(ciphertext);
2496
+ unseal: (acp, ciphertext) => {
2497
+ return unsealWithPrivateKey(acp.sealingPrivateKey, ciphertext);
2525
2498
  },
2526
2499
  /**
2527
- * Check if permit is expired
2500
+ * Check if acp is expired
2528
2501
  */
2529
- isExpired: (permit) => {
2530
- return ValidationUtils.isExpired(permit);
2502
+ isExpired: (acp) => {
2503
+ return ValidationUtils.isExpired(acp);
2531
2504
  },
2532
2505
  /**
2533
- * Check if permit is signed
2506
+ * Check if acp is signed
2534
2507
  */
2535
- isSigned: (permit) => {
2536
- return ValidationUtils.isSigned(permit);
2508
+ isSigned: (acp) => {
2509
+ return ValidationUtils.isSigned(acp);
2537
2510
  },
2538
2511
  /**
2539
- * Check if permit is signed and not expired
2512
+ * Check if acp is signed and not expired
2540
2513
  */
2541
- isSignedAndNotExpired: (permit) => {
2542
- return ValidationUtils.isSignedAndNotExpired(permit);
2514
+ isSignedAndNotExpired: (acp) => {
2515
+ return ValidationUtils.isSignedAndNotExpired(acp);
2543
2516
  },
2544
2517
  /**
2545
- * Assert that permit is signed and not expired
2518
+ * Assert that acp is signed and not expired
2546
2519
  */
2547
- assertSignedAndNotExpired: (permit) => {
2548
- return ValidationUtils.assertSignedAndNotExpired(permit);
2520
+ assertSignedAndNotExpired: (acp) => {
2521
+ return ValidationUtils.assertSignedAndNotExpired(acp);
2549
2522
  },
2550
- isValid: (permit) => {
2551
- return ValidationUtils.isValid(permit);
2523
+ isValid: (acp) => {
2524
+ return ValidationUtils.isValid(acp);
2552
2525
  },
2553
2526
  /**
2554
- * Update permit name (returns new permit instance)
2527
+ * Update acp name (returns new acp instance)
2555
2528
  */
2556
- updateName: (permit, name) => {
2557
- return { ...permit, name };
2529
+ updateName: (acp, name) => {
2530
+ return { ...acp, name };
2558
2531
  },
2559
2532
  /**
2560
2533
  * Fetch EIP712 domain from the blockchain
@@ -2563,230 +2536,468 @@ var PermitUtils = {
2563
2536
  return getAclEIP712Domain(publicClient);
2564
2537
  },
2565
2538
  /**
2566
- * Check if permit's signed domain matches the provided domain
2539
+ * Check if acp's signed domain matches the provided domain
2567
2540
  */
2568
- matchesDomain: (permit, domain) => {
2569
- return permit._signedDomain?.name === domain.name && permit._signedDomain?.version === domain.version && permit._signedDomain?.verifyingContract === domain.verifyingContract && permit._signedDomain?.chainId === domain.chainId;
2541
+ matchesDomain: (acp, domain) => {
2542
+ return acp._signedDomain?.name === domain.name && acp._signedDomain?.version === domain.version && acp._signedDomain?.verifyingContract === domain.verifyingContract && acp._signedDomain?.chainId === domain.chainId;
2570
2543
  },
2571
2544
  /**
2572
- * Check if permit's signed domain is valid for the current chain
2545
+ * Check if acp's signed domain is valid for the current chain
2573
2546
  */
2574
- checkSignedDomainValid: async (permit, publicClient) => {
2575
- if (permit._signedDomain == null)
2547
+ checkSignedDomainValid: async (acp, publicClient) => {
2548
+ if (acp._signedDomain == null)
2576
2549
  return false;
2577
2550
  const domain = await getAclEIP712Domain(publicClient);
2578
- return PermitUtils.matchesDomain(permit, domain);
2551
+ return ACPUtils.matchesDomain(acp, domain);
2579
2552
  },
2580
2553
  /**
2581
- * Check if permit passes the on-chain validation
2554
+ * Check if acp passes the on-chain validation
2582
2555
  */
2583
- checkValidityOnChain: async (permit, publicClient) => {
2584
- const permission = PermitUtils.getPermission(permit);
2585
- return checkPermitValidityOnChain(permission, publicClient);
2556
+ checkValidityOnChain: async (acp, publicClient) => {
2557
+ const publicAcp = ACPUtils.getPublic(acp);
2558
+ return checkACPValidityOnChain(publicAcp, publicClient);
2586
2559
  }
2587
2560
  };
2588
- var PERMIT_STORE_DEFAULTS = {
2589
- permits: {},
2590
- activePermitHash: {}
2561
+ var ACP_STORE_DEFAULTS = {
2562
+ acps: {},
2563
+ activeACPHash: {}
2591
2564
  };
2592
- var _permitStore = vanilla.createStore()(
2593
- middleware.persist(() => PERMIT_STORE_DEFAULTS, { name: "cofhesdk-permits" })
2565
+ var ACP_STORE_VERSION = 3;
2566
+ var _acpStore = vanilla.createStore()(
2567
+ middleware.persist(() => ACP_STORE_DEFAULTS, {
2568
+ name: "cofhesdk-acps",
2569
+ version: ACP_STORE_VERSION,
2570
+ migrate: (persistedState, version) => {
2571
+ if (version < ACP_STORE_VERSION)
2572
+ return ACP_STORE_DEFAULTS;
2573
+ return persistedState;
2574
+ }
2575
+ })
2594
2576
  );
2595
2577
  var clearStaleStore = () => {
2596
- const state = _permitStore.getState();
2597
- const hasExpectedStructure = state && typeof state === "object" && "permits" in state && "activePermitHash" in state && typeof state.permits === "object" && typeof state.activePermitHash === "object";
2578
+ const state = _acpStore.getState();
2579
+ const hasExpectedStructure = state && typeof state === "object" && "acps" in state && "activeACPHash" in state && typeof state.acps === "object" && typeof state.activeACPHash === "object";
2598
2580
  if (hasExpectedStructure)
2599
2581
  return;
2600
- _permitStore.setState({ permits: {}, activePermitHash: {} });
2582
+ _acpStore.setState({ acps: {}, activeACPHash: {} });
2601
2583
  };
2602
- var getPermit = (chainId, account, hash) => {
2584
+ var getACP = (chainId, account, hash) => {
2603
2585
  clearStaleStore();
2604
2586
  if (chainId == null || account == null || hash == null)
2605
2587
  return;
2606
- const savedPermit = _permitStore.getState().permits[chainId]?.[account]?.[hash];
2607
- if (savedPermit == null)
2588
+ const savedACP = _acpStore.getState().acps[chainId]?.[account]?.[hash];
2589
+ if (savedACP == null)
2608
2590
  return;
2609
- return PermitUtils.deserialize(savedPermit);
2591
+ return ACPUtils.deserialize(savedACP);
2610
2592
  };
2611
- var getActivePermit = (chainId, account) => {
2593
+ var getActiveACP = (chainId, account) => {
2612
2594
  clearStaleStore();
2613
2595
  if (chainId == null || account == null)
2614
2596
  return;
2615
- const activePermitHash = _permitStore.getState().activePermitHash[chainId]?.[account];
2616
- return getPermit(chainId, account, activePermitHash);
2597
+ const activeACPHash = _acpStore.getState().activeACPHash[chainId]?.[account];
2598
+ return getACP(chainId, account, activeACPHash);
2617
2599
  };
2618
- var getPermits = (chainId, account) => {
2600
+ var getACPs = (chainId, account) => {
2619
2601
  clearStaleStore();
2620
2602
  if (chainId == null || account == null)
2621
2603
  return {};
2622
- return Object.entries(_permitStore.getState().permits[chainId]?.[account] ?? {}).reduce(
2623
- (acc, [hash, permit]) => {
2624
- if (permit == void 0)
2604
+ return Object.entries(_acpStore.getState().acps[chainId]?.[account] ?? {}).reduce(
2605
+ (acc, [hash, acp]) => {
2606
+ if (acp == void 0)
2625
2607
  return acc;
2626
- return { ...acc, [hash]: PermitUtils.deserialize(permit) };
2608
+ return { ...acc, [hash]: ACPUtils.deserialize(acp) };
2627
2609
  },
2628
2610
  {}
2629
2611
  );
2630
2612
  };
2631
- var setPermit = (chainId, account, permit) => {
2613
+ var setACP = (chainId, account, acp) => {
2632
2614
  clearStaleStore();
2633
- _permitStore.setState(
2615
+ _acpStore.setState(
2634
2616
  immer.produce((state) => {
2635
- if (state.permits[chainId] == null)
2636
- state.permits[chainId] = {};
2637
- if (state.permits[chainId][account] == null)
2638
- state.permits[chainId][account] = {};
2639
- state.permits[chainId][account][permit.hash] = PermitUtils.serialize(permit);
2617
+ if (state.acps[chainId] == null)
2618
+ state.acps[chainId] = {};
2619
+ if (state.acps[chainId][account] == null)
2620
+ state.acps[chainId][account] = {};
2621
+ state.acps[chainId][account][acp.hash] = ACPUtils.serialize(acp);
2640
2622
  })
2641
2623
  );
2642
2624
  };
2643
- var removePermit = (chainId, account, hash) => {
2625
+ var removeACP = (chainId, account, hash) => {
2644
2626
  clearStaleStore();
2645
- _permitStore.setState(
2627
+ _acpStore.setState(
2646
2628
  immer.produce((state) => {
2647
- if (state.permits[chainId] == null)
2648
- state.permits[chainId] = {};
2649
- if (state.activePermitHash[chainId] == null)
2650
- state.activePermitHash[chainId] = {};
2651
- const accountPermits = state.permits[chainId][account];
2652
- if (accountPermits == null)
2629
+ if (state.acps[chainId] == null)
2630
+ state.acps[chainId] = {};
2631
+ if (state.activeACPHash[chainId] == null)
2632
+ state.activeACPHash[chainId] = {};
2633
+ const accountACPs = state.acps[chainId][account];
2634
+ if (accountACPs == null)
2653
2635
  return;
2654
- if (accountPermits[hash] == null)
2636
+ if (accountACPs[hash] == null)
2655
2637
  return;
2656
- if (state.activePermitHash[chainId][account] === hash) {
2657
- state.activePermitHash[chainId][account] = void 0;
2638
+ if (state.activeACPHash[chainId][account] === hash) {
2639
+ state.activeACPHash[chainId][account] = void 0;
2658
2640
  }
2659
- accountPermits[hash] = void 0;
2641
+ accountACPs[hash] = void 0;
2660
2642
  })
2661
2643
  );
2662
2644
  };
2663
- var getActivePermitHash = (chainId, account) => {
2645
+ var getActiveACPHash = (chainId, account) => {
2664
2646
  clearStaleStore();
2665
2647
  if (chainId == null || account == null)
2666
2648
  return void 0;
2667
- return _permitStore.getState().activePermitHash[chainId]?.[account];
2649
+ return _acpStore.getState().activeACPHash[chainId]?.[account];
2668
2650
  };
2669
- var setActivePermitHash = (chainId, account, hash) => {
2651
+ var setActiveACPHash = (chainId, account, hash) => {
2670
2652
  clearStaleStore();
2671
- _permitStore.setState(
2653
+ _acpStore.setState(
2672
2654
  immer.produce((state) => {
2673
- if (state.activePermitHash[chainId] == null)
2674
- state.activePermitHash[chainId] = {};
2675
- state.activePermitHash[chainId][account] = hash;
2655
+ if (state.activeACPHash[chainId] == null)
2656
+ state.activeACPHash[chainId] = {};
2657
+ state.activeACPHash[chainId][account] = hash;
2676
2658
  })
2677
2659
  );
2678
2660
  };
2679
- var removeActivePermitHash = (chainId, account) => {
2661
+ var removeActiveACPHash = (chainId, account) => {
2680
2662
  clearStaleStore();
2681
- _permitStore.setState(
2663
+ _acpStore.setState(
2682
2664
  immer.produce((state) => {
2683
- if (state.activePermitHash[chainId])
2684
- state.activePermitHash[chainId][account] = void 0;
2665
+ if (state.activeACPHash[chainId])
2666
+ state.activeACPHash[chainId][account] = void 0;
2685
2667
  })
2686
2668
  );
2687
2669
  };
2688
2670
  var resetStore = () => {
2689
2671
  clearStaleStore();
2690
- _permitStore.setState({ permits: {}, activePermitHash: {} });
2672
+ _acpStore.setState({ acps: {}, activeACPHash: {} });
2691
2673
  };
2692
- var permitStore = {
2693
- store: _permitStore,
2694
- getPermit,
2695
- getActivePermit,
2696
- getPermits,
2697
- setPermit,
2698
- removePermit,
2699
- getActivePermitHash,
2700
- setActivePermitHash,
2701
- removeActivePermitHash,
2674
+ var acpStore = {
2675
+ store: _acpStore,
2676
+ getACP,
2677
+ getActiveACP,
2678
+ getACPs,
2679
+ setACP,
2680
+ removeACP,
2681
+ getActiveACPHash,
2682
+ setActiveACPHash,
2683
+ removeActiveACPHash,
2702
2684
  resetStore
2703
2685
  };
2704
- var storeActivePermit = async (permit, publicClient, walletClient) => {
2686
+ var ACP_VALIDATOR_ABI = viem.parseAbi([
2687
+ "function revokeSingle(uint256 id)",
2688
+ "function revokeAllExisting()",
2689
+ "function disabled(address issuer, uint256 id) view returns (bool)"
2690
+ ]);
2691
+ var storeACP = async (acp, publicClient, walletClient) => {
2705
2692
  const chainId = await publicClient.getChainId();
2706
2693
  const account = walletClient.account.address;
2707
- permitStore.setPermit(chainId, account, permit);
2708
- permitStore.setActivePermitHash(chainId, account, permit.hash);
2694
+ acpStore.setACP(chainId, account, acp);
2709
2695
  };
2710
- var createPermitWithSign = async (options, publicClient, walletClient, permitMethod) => {
2711
- const permit = await permitMethod(options, publicClient, walletClient);
2712
- await storeActivePermit(permit, publicClient, walletClient);
2713
- return permit;
2696
+ var storeActiveACP = async (acp, publicClient, walletClient) => {
2697
+ await storeACP(acp, publicClient, walletClient);
2698
+ const chainId = await publicClient.getChainId();
2699
+ const account = walletClient.account.address;
2700
+ acpStore.setActiveACPHash(chainId, account, acp.hash);
2701
+ };
2702
+ var createACPWithSign = async (options, publicClient, walletClient, acpMethod, activate = true) => {
2703
+ const acp = await acpMethod(options, publicClient, walletClient);
2704
+ if (activate) {
2705
+ await storeActiveACP(acp, publicClient, walletClient);
2706
+ } else {
2707
+ await storeACP(acp, publicClient, walletClient);
2708
+ }
2709
+ return acp;
2714
2710
  };
2715
2711
  var createSelf = async (options, publicClient, walletClient) => {
2716
- return createPermitWithSign(options, publicClient, walletClient, PermitUtils.createSelfAndSign);
2712
+ return createACPWithSign(options, publicClient, walletClient, ACPUtils.createSelfAndSign);
2717
2713
  };
2718
2714
  var createSharing = async (options, publicClient, walletClient) => {
2719
- return createPermitWithSign(options, publicClient, walletClient, PermitUtils.createSharingAndSign);
2715
+ return createACPWithSign(options, publicClient, walletClient, ACPUtils.createSharingAndSign, false);
2720
2716
  };
2721
2717
  var importShared = async (options, publicClient, walletClient) => {
2722
- return createPermitWithSign(options, publicClient, walletClient, PermitUtils.importSharedAndSign);
2718
+ return createACPWithSign(options, publicClient, walletClient, ACPUtils.importSharedAndSign);
2723
2719
  };
2724
- var getHash = (permit) => {
2725
- return PermitUtils.getHash(permit);
2720
+ var getHash = (acp) => {
2721
+ return ACPUtils.getHash(acp);
2726
2722
  };
2727
- var exportShared = (permit) => {
2728
- return PermitUtils.export(permit);
2723
+ var exportShared = (acp) => {
2724
+ return ACPUtils.export(acp);
2729
2725
  };
2730
- var serialize = (permit) => {
2731
- return PermitUtils.serialize(permit);
2726
+ var serialize = (acp) => {
2727
+ return ACPUtils.serialize(acp);
2732
2728
  };
2733
2729
  var deserialize = (serialized) => {
2734
- return PermitUtils.deserialize(serialized);
2730
+ return ACPUtils.deserialize(serialized);
2735
2731
  };
2736
- var getPermit2 = (chainId, account, hash) => {
2737
- return permitStore.getPermit(chainId, account, hash);
2732
+ var getACP2 = (chainId, account, hash) => {
2733
+ return acpStore.getACP(chainId, account, hash);
2738
2734
  };
2739
- var getPermits2 = (chainId, account) => {
2740
- return permitStore.getPermits(chainId, account);
2735
+ var getACPs2 = (chainId, account) => {
2736
+ return acpStore.getACPs(chainId, account);
2741
2737
  };
2742
- var getActivePermit2 = (chainId, account) => {
2743
- return permitStore.getActivePermit(chainId, account);
2738
+ var getActiveACP2 = (chainId, account) => {
2739
+ return acpStore.getActiveACP(chainId, account);
2744
2740
  };
2745
- var getActivePermitHash2 = (chainId, account) => {
2746
- return permitStore.getActivePermitHash(chainId, account);
2741
+ var getActiveACPHash2 = (chainId, account) => {
2742
+ return acpStore.getActiveACPHash(chainId, account);
2747
2743
  };
2748
- var selectActivePermit = (chainId, account, hash) => {
2749
- permitStore.setActivePermitHash(chainId, account, hash);
2744
+ var selectActiveACP = (chainId, account, hash) => {
2745
+ acpStore.setActiveACPHash(chainId, account, hash);
2750
2746
  };
2751
- var getOrCreateSelfPermit = async (publicClient, walletClient, chainId, account, options) => {
2747
+ var getOrCreateSelfACP = async (publicClient, walletClient, chainId, account, options) => {
2752
2748
  const _chainId = chainId ?? await publicClient.getChainId();
2753
2749
  const _account = account ?? walletClient.account.address;
2754
- const activePermit = await getActivePermit2(_chainId, _account);
2755
- if (activePermit && activePermit.type === "self") {
2756
- return activePermit;
2750
+ const activeACP = await getActiveACP2(_chainId, _account);
2751
+ if (activeACP && activeACP.type === "self" && ACPUtils.isValid(activeACP).valid) {
2752
+ return activeACP;
2757
2753
  }
2758
- return createSelf(options ?? { issuer: _account, name: "Autogenerated Self Permit" }, publicClient, walletClient);
2754
+ return createSelf(options ?? { issuer: _account, name: "Autogenerated Self ACP" }, publicClient, walletClient);
2759
2755
  };
2760
- var getOrCreateSharingPermit = async (publicClient, walletClient, options, chainId, account) => {
2756
+ var getOrCreateSharingACP = async (publicClient, walletClient, options, chainId, account) => {
2761
2757
  const _chainId = chainId ?? await publicClient.getChainId();
2762
2758
  const _account = account ?? walletClient.account.address;
2763
- const activePermit = await getActivePermit2(_chainId, _account);
2764
- if (activePermit && activePermit.type === "sharing") {
2765
- return activePermit;
2759
+ const activeACP = await getActiveACP2(_chainId, _account);
2760
+ if (activeACP && activeACP.type === "sharing" && ACPUtils.isValid(activeACP).valid) {
2761
+ return activeACP;
2766
2762
  }
2767
2763
  return createSharing(options, publicClient, walletClient);
2768
2764
  };
2769
- var removePermit2 = async (chainId, account, hash) => permitStore.removePermit(chainId, account, hash);
2770
- var removeActivePermit = async (chainId, account) => permitStore.removeActivePermitHash(chainId, account);
2771
- var permits = {
2772
- getSnapshot: permitStore.store.getState,
2773
- subscribe: permitStore.store.subscribe,
2765
+ var applyACPDefaults = (options, acpConfig, chainId) => {
2766
+ const result = { ...options };
2767
+ const defaultRevoker = acpConfig?.defaultRevoker?.[chainId];
2768
+ const hasValidatorOptions = options.revokerData != null || options.revokerContract != null;
2769
+ if (defaultRevoker != null && !hasValidatorOptions) {
2770
+ result.revokerContract = defaultRevoker;
2771
+ result.revokerData = Math.round(Date.now() / 1e3) - 60;
2772
+ }
2773
+ const defaultContracts = acpConfig?.defaultContractScopes?.[chainId];
2774
+ const hasScopeOptions = options.scope != null || options.contracts != null || options.handles != null;
2775
+ if (defaultContracts != null && defaultContracts.length > 0 && !hasScopeOptions) {
2776
+ result.contracts = defaultContracts;
2777
+ }
2778
+ return result;
2779
+ };
2780
+ var ACL_SERVED_ADDRESSES_ABI = viem.parseAbi([
2781
+ "function acl() view returns (address)",
2782
+ "function defaultRevokerContract() view returns (address)",
2783
+ "function shareRegistry() view returns (address)"
2784
+ ]);
2785
+ var aclServedAddressesCache = /* @__PURE__ */ new Map();
2786
+ var clearAclServedAddresses = () => aclServedAddressesCache.clear();
2787
+ var getAclServedAddresses = async (publicClient, chainId) => {
2788
+ const cached = aclServedAddressesCache.get(chainId);
2789
+ if (cached != null)
2790
+ return cached;
2791
+ let aclAddress;
2792
+ try {
2793
+ aclAddress = await publicClient.readContract({
2794
+ address: TASK_MANAGER_ADDRESS,
2795
+ abi: ACL_SERVED_ADDRESSES_ABI,
2796
+ functionName: "acl"
2797
+ });
2798
+ } catch {
2799
+ return {};
2800
+ }
2801
+ const [defaultRevoker, shareRegistry] = await Promise.all([
2802
+ publicClient.readContract({ address: aclAddress, abi: ACL_SERVED_ADDRESSES_ABI, functionName: "defaultRevokerContract" }).catch(() => void 0),
2803
+ publicClient.readContract({ address: aclAddress, abi: ACL_SERVED_ADDRESSES_ABI, functionName: "shareRegistry" }).catch(() => void 0)
2804
+ ]);
2805
+ const resolved = {
2806
+ defaultRevoker: defaultRevoker != null && defaultRevoker !== viem.zeroAddress ? defaultRevoker : void 0,
2807
+ shareRegistry: shareRegistry != null && shareRegistry !== viem.zeroAddress ? shareRegistry : void 0
2808
+ };
2809
+ aclServedAddressesCache.set(chainId, resolved);
2810
+ return resolved;
2811
+ };
2812
+ var applyACPDefaultsFromChain = async (options, acpConfig, publicClient, chainId) => {
2813
+ const hasExplicitRevoker = acpConfig?.defaultRevoker?.[chainId] != null || options.revokerData != null || options.revokerContract != null;
2814
+ if (hasExplicitRevoker)
2815
+ return applyACPDefaults(options, acpConfig, chainId);
2816
+ const served = await getAclServedAddresses(publicClient, chainId);
2817
+ const effectiveConfig = served.defaultRevoker != null ? { ...acpConfig, defaultRevoker: { ...acpConfig?.defaultRevoker, [chainId]: served.defaultRevoker } } : acpConfig;
2818
+ return applyACPDefaults(options, effectiveConfig, chainId);
2819
+ };
2820
+ var revokeACP = async (acp, walletClient) => {
2821
+ if (acp.revokerContract === viem.zeroAddress || acp.revokerData === 0) {
2822
+ throw new Error("ACP is not revocable: it has no revoker (revokerContract/revokerData unset)");
2823
+ }
2824
+ if (walletClient.account == null)
2825
+ throw new Error("Missing walletClient account");
2826
+ if (walletClient.account.address.toLowerCase() !== acp.issuer.toLowerCase()) {
2827
+ throw new Error("Only the acp issuer can revoke it");
2828
+ }
2829
+ return walletClient.writeContract({
2830
+ address: acp.revokerContract,
2831
+ abi: ACP_VALIDATOR_ABI,
2832
+ functionName: "revokeSingle",
2833
+ args: [BigInt(acp.revokerData)],
2834
+ account: walletClient.account,
2835
+ chain: walletClient.chain
2836
+ });
2837
+ };
2838
+ var revokeAllACPs = async (walletClient, publicClient, revokerContract) => {
2839
+ if (walletClient.account == null)
2840
+ throw new Error("Missing walletClient account");
2841
+ let revoker = revokerContract;
2842
+ if (revoker == null) {
2843
+ const chainId = await publicClient.getChainId();
2844
+ const active = getActiveACP2(chainId, walletClient.account.address);
2845
+ revoker = active?.revokerContract;
2846
+ }
2847
+ if (revoker == null || revoker === viem.zeroAddress) {
2848
+ throw new Error("No revoker contract: pass `revokerContract` or activate a revocable acp first");
2849
+ }
2850
+ return walletClient.writeContract({
2851
+ address: revoker,
2852
+ abi: ACP_VALIDATOR_ABI,
2853
+ functionName: "revokeAllExisting",
2854
+ args: [],
2855
+ account: walletClient.account,
2856
+ chain: walletClient.chain
2857
+ });
2858
+ };
2859
+ var isACPRevoked = async (acp, publicClient) => {
2860
+ if (acp.revokerContract === viem.zeroAddress || acp.revokerData === 0)
2861
+ return false;
2862
+ return publicClient.readContract({
2863
+ address: acp.revokerContract,
2864
+ abi: ACP_VALIDATOR_ABI,
2865
+ functionName: "disabled",
2866
+ args: [acp.issuer, BigInt(acp.revokerData)]
2867
+ });
2868
+ };
2869
+ var ACP_SHARE_REGISTRY_ABI = viem.parseAbi([
2870
+ "struct ACP { address issuer; uint64 expiration; address recipient; uint256 revokerData; address revokerContract; uint8 scope; address[] contracts; bytes32[] handles; bytes32 sealingKey; bytes issuerSignature; bytes recipientSignature; }",
2871
+ "function share(ACP calldata acp) external returns (bytes32)",
2872
+ "function removeShare(bytes32 shareId) external",
2873
+ "function sharesFor(address recipient) external view returns (ACP[] memory)",
2874
+ "function getShare(bytes32 shareId) external view returns (ACP memory)",
2875
+ "function isShareValid(bytes32 shareId) external view returns (bool)"
2876
+ ]);
2877
+ var ACP_TUPLE = [
2878
+ {
2879
+ type: "tuple",
2880
+ components: [
2881
+ { name: "issuer", type: "address" },
2882
+ { name: "expiration", type: "uint64" },
2883
+ { name: "recipient", type: "address" },
2884
+ { name: "revokerData", type: "uint256" },
2885
+ { name: "revokerContract", type: "address" },
2886
+ { name: "scope", type: "uint8" },
2887
+ { name: "contracts", type: "address[]" },
2888
+ { name: "handles", type: "bytes32[]" },
2889
+ { name: "sealingKey", type: "bytes32" },
2890
+ { name: "issuerSignature", type: "bytes" },
2891
+ { name: "recipientSignature", type: "bytes" }
2892
+ ]
2893
+ }
2894
+ ];
2895
+ var ZERO_BYTES32 = `0x${"0".repeat(64)}`;
2896
+ var toChainShare = (acp) => {
2897
+ const pub = ACPUtils.getPublic(acp, true);
2898
+ return {
2899
+ ...pub,
2900
+ expiration: BigInt(pub.expiration),
2901
+ revokerData: BigInt(pub.revokerData),
2902
+ sealingKey: ZERO_BYTES32,
2903
+ recipientSignature: "0x"
2904
+ };
2905
+ };
2906
+ var computeShareId = (acp) => {
2907
+ const p = toChainShare(acp);
2908
+ return viem.keccak256(viem.encodeAbiParameters(ACP_TUPLE, [p]));
2909
+ };
2910
+ var shareOnChain = async (acp, walletClient, registry) => {
2911
+ if (acp.type !== "sharing") {
2912
+ throw new Error(`Cannot share a '${acp.type}' ACP on-chain \u2014 only 'sharing' ACPs are shareable.`);
2913
+ }
2914
+ if (acp.issuerSignature === "0x") {
2915
+ throw new Error("Cannot share an unsigned sharing ACP \u2014 sign it first.");
2916
+ }
2917
+ if (walletClient.account == null)
2918
+ throw new Error("Missing walletClient account");
2919
+ if (walletClient.account.address.toLowerCase() !== acp.issuer.toLowerCase()) {
2920
+ throw new Error("Only the ACP issuer can share it on-chain");
2921
+ }
2922
+ const txHash = await walletClient.writeContract({
2923
+ address: registry,
2924
+ abi: ACP_SHARE_REGISTRY_ABI,
2925
+ functionName: "share",
2926
+ args: [toChainShare(acp)],
2927
+ account: walletClient.account,
2928
+ chain: walletClient.chain ?? null
2929
+ });
2930
+ return { txHash, shareId: computeShareId(acp) };
2931
+ };
2932
+ var getIncomingShares = async (publicClient, registry, recipient) => {
2933
+ const raw = await publicClient.readContract({
2934
+ address: registry,
2935
+ abi: ACP_SHARE_REGISTRY_ABI,
2936
+ functionName: "sharesFor",
2937
+ args: [recipient]
2938
+ });
2939
+ return raw.map((s) => ({
2940
+ shareId: viem.keccak256(viem.encodeAbiParameters(ACP_TUPLE, [s])),
2941
+ issuer: s.issuer,
2942
+ expiration: Number(s.expiration),
2943
+ recipient: s.recipient,
2944
+ revokerData: Number(s.revokerData),
2945
+ revokerContract: s.revokerContract,
2946
+ scope: Number(s.scope),
2947
+ contracts: [...s.contracts],
2948
+ handles: [...s.handles],
2949
+ issuerSignature: s.issuerSignature
2950
+ }));
2951
+ };
2952
+ var importFromChain = async (share, publicClient, walletClient) => {
2953
+ const { shareId: _shareId, ...options } = share;
2954
+ return importShared({ ...options, type: "sharing" }, publicClient, walletClient);
2955
+ };
2956
+ var removeShareOnChain = async (shareId, walletClient, registry) => {
2957
+ if (walletClient.account == null)
2958
+ throw new Error("Missing walletClient account");
2959
+ return walletClient.writeContract({
2960
+ address: registry,
2961
+ abi: ACP_SHARE_REGISTRY_ABI,
2962
+ functionName: "removeShare",
2963
+ args: [shareId],
2964
+ account: walletClient.account,
2965
+ chain: walletClient.chain ?? null
2966
+ });
2967
+ };
2968
+ var removeACP2 = async (chainId, account, hash) => acpStore.removeACP(chainId, account, hash);
2969
+ var removeActiveACP = async (chainId, account) => acpStore.removeActiveACPHash(chainId, account);
2970
+ var acps = {
2971
+ getSnapshot: acpStore.store.getState,
2972
+ subscribe: acpStore.store.subscribe,
2774
2973
  createSelf,
2775
2974
  createSharing,
2776
2975
  importShared,
2777
- getOrCreateSelfPermit,
2778
- getOrCreateSharingPermit,
2976
+ getOrCreateSelfACP,
2977
+ getOrCreateSharingACP,
2779
2978
  getHash,
2780
2979
  export: exportShared,
2781
2980
  serialize,
2782
2981
  deserialize,
2783
- getPermit: getPermit2,
2784
- getPermits: getPermits2,
2785
- getActivePermit: getActivePermit2,
2786
- getActivePermitHash: getActivePermitHash2,
2787
- removePermit: removePermit2,
2788
- selectActivePermit,
2789
- removeActivePermit
2982
+ getACP: getACP2,
2983
+ getACPs: getACPs2,
2984
+ getActiveACP: getActiveACP2,
2985
+ getActiveACPHash: getActiveACPHash2,
2986
+ removeACP: removeACP2,
2987
+ selectActiveACP,
2988
+ removeActiveACP,
2989
+ revokeACP,
2990
+ revokeAllACPs,
2991
+ isACPRevoked,
2992
+ shareOnChain,
2993
+ getIncomingShares,
2994
+ importFromChain,
2995
+ removeShareOnChain,
2996
+ computeShareId,
2997
+ applyACPDefaults,
2998
+ applyACPDefaultsFromChain,
2999
+ getAclServedAddresses,
3000
+ clearAclServedAddresses
2790
3001
  };
2791
3002
  function uint160ToAddress(uint160) {
2792
3003
  const hexStr = uint160.toString(16).padStart(40, "0");
@@ -2849,13 +3060,16 @@ var MockThresholdNetworkAbi = [
2849
3060
  {
2850
3061
  name: "permission",
2851
3062
  type: "tuple",
2852
- internalType: "struct Permission",
3063
+ internalType: "struct ACPermission",
2853
3064
  components: [
2854
3065
  { name: "issuer", type: "address", internalType: "address" },
2855
3066
  { name: "expiration", type: "uint64", internalType: "uint64" },
2856
3067
  { name: "recipient", type: "address", internalType: "address" },
2857
- { name: "validatorId", type: "uint256", internalType: "uint256" },
2858
- { name: "validatorContract", type: "address", internalType: "address" },
3068
+ { name: "revokerData", type: "uint256", internalType: "uint256" },
3069
+ { name: "revokerContract", type: "address", internalType: "address" },
3070
+ { name: "scope", type: "uint8", internalType: "uint8" },
3071
+ { name: "contracts", type: "address[]", internalType: "address[]" },
3072
+ { name: "handles", type: "bytes32[]", internalType: "bytes32[]" },
2859
3073
  { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2860
3074
  { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2861
3075
  { name: "recipientSignature", type: "bytes", internalType: "bytes" }
@@ -2878,13 +3092,16 @@ var MockThresholdNetworkAbi = [
2878
3092
  {
2879
3093
  name: "permission",
2880
3094
  type: "tuple",
2881
- internalType: "struct Permission",
3095
+ internalType: "struct ACPermission",
2882
3096
  components: [
2883
3097
  { name: "issuer", type: "address", internalType: "address" },
2884
3098
  { name: "expiration", type: "uint64", internalType: "uint64" },
2885
3099
  { name: "recipient", type: "address", internalType: "address" },
2886
- { name: "validatorId", type: "uint256", internalType: "uint256" },
2887
- { name: "validatorContract", type: "address", internalType: "address" },
3100
+ { name: "revokerData", type: "uint256", internalType: "uint256" },
3101
+ { name: "revokerContract", type: "address", internalType: "address" },
3102
+ { name: "scope", type: "uint8", internalType: "uint8" },
3103
+ { name: "contracts", type: "address[]", internalType: "address[]" },
3104
+ { name: "handles", type: "bytes32[]", internalType: "bytes32[]" },
2888
3105
  { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2889
3106
  { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2890
3107
  { name: "recipientSignature", type: "bytes", internalType: "bytes" }
@@ -2949,19 +3166,22 @@ var MockThresholdNetworkAbi = [
2949
3166
  },
2950
3167
  {
2951
3168
  type: "function",
2952
- name: "decryptForTxWithPermit",
3169
+ name: "decryptForTxWithACP",
2953
3170
  inputs: [
2954
3171
  { name: "ctHash", type: "uint256", internalType: "uint256" },
2955
3172
  {
2956
3173
  name: "permission",
2957
3174
  type: "tuple",
2958
- internalType: "struct Permission",
3175
+ internalType: "struct ACPermission",
2959
3176
  components: [
2960
3177
  { name: "issuer", type: "address", internalType: "address" },
2961
3178
  { name: "expiration", type: "uint64", internalType: "uint64" },
2962
3179
  { name: "recipient", type: "address", internalType: "address" },
2963
- { name: "validatorId", type: "uint256", internalType: "uint256" },
2964
- { name: "validatorContract", type: "address", internalType: "address" },
3180
+ { name: "revokerData", type: "uint256", internalType: "uint256" },
3181
+ { name: "revokerContract", type: "address", internalType: "address" },
3182
+ { name: "scope", type: "uint8", internalType: "uint8" },
3183
+ { name: "contracts", type: "address[]", internalType: "address[]" },
3184
+ { name: "handles", type: "bytes32[]", internalType: "bytes32[]" },
2965
3185
  { name: "sealingKey", type: "bytes32", internalType: "bytes32" },
2966
3186
  { name: "issuerSignature", type: "bytes", internalType: "bytes" },
2967
3187
  { name: "recipientSignature", type: "bytes", internalType: "bytes" }
@@ -2977,7 +3197,7 @@ var MockThresholdNetworkAbi = [
2977
3197
  },
2978
3198
  {
2979
3199
  type: "function",
2980
- name: "decryptForTxWithoutPermit",
3200
+ name: "decryptForTxWithoutACP",
2981
3201
  inputs: [{ name: "ctHash", type: "uint256", internalType: "uint256" }],
2982
3202
  outputs: [
2983
3203
  { name: "allowed", type: "bool", internalType: "bool" },
@@ -2989,12 +3209,12 @@ var MockThresholdNetworkAbi = [
2989
3209
  ];
2990
3210
 
2991
3211
  // core/decrypt/cofheMocksDecryptForView.ts
2992
- async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient) {
2993
- const permission = PermitUtils.getPermission(permit, true);
3212
+ async function cofheMocksDecryptForView(ctHash, utype, acp, publicClient) {
3213
+ const wireAcp = ACPUtils.getPublic(acp, true);
2994
3214
  const permissionWithBigInts = {
2995
- ...permission,
2996
- expiration: BigInt(permission.expiration),
2997
- validatorId: BigInt(permission.validatorId)
3215
+ ...wireAcp,
3216
+ expiration: BigInt(wireAcp.expiration),
3217
+ revokerData: BigInt(wireAcp.revokerData)
2998
3218
  };
2999
3219
  const [allowed, error, result] = await publicClient.readContract({
3000
3220
  address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
@@ -3015,11 +3235,41 @@ async function cofheMocksDecryptForView(ctHash, utype, permit, publicClient) {
3015
3235
  });
3016
3236
  }
3017
3237
  const sealedBigInt = BigInt(result);
3018
- const sealingKeyBigInt = BigInt(permission.sealingKey);
3238
+ const sealingKeyBigInt = BigInt(acp.sealingKey);
3019
3239
  const unsealed = sealedBigInt ^ sealingKeyBigInt;
3020
3240
  return unsealed;
3021
3241
  }
3022
3242
 
3243
+ // core/debug.ts
3244
+ var interceptors = {};
3245
+ function setCofheDebugInterceptors(next) {
3246
+ interceptors.onRequest = next?.onRequest;
3247
+ interceptors.onResponse = next?.onResponse;
3248
+ }
3249
+ function getCofheDebugInterceptors() {
3250
+ return interceptors;
3251
+ }
3252
+ async function cofheFetch(url, init, ctx = { op: "request" }) {
3253
+ let finalUrl = url;
3254
+ let finalInit = init;
3255
+ if (interceptors.onRequest) {
3256
+ const override = await interceptors.onRequest(finalUrl, finalInit, ctx);
3257
+ if (override) {
3258
+ if (override.url !== void 0)
3259
+ finalUrl = override.url;
3260
+ if (override.init !== void 0)
3261
+ finalInit = override.init;
3262
+ }
3263
+ }
3264
+ let response = await fetch(finalUrl, finalInit);
3265
+ if (interceptors.onResponse) {
3266
+ const replaced = await interceptors.onResponse(response, ctx);
3267
+ if (replaced)
3268
+ response = replaced;
3269
+ }
3270
+ return response;
3271
+ }
3272
+
3023
3273
  // core/decrypt/polling.ts
3024
3274
  function computeMinuteRampPollIntervalMs(elapsedMs, params) {
3025
3275
  const elapsedSeconds = Math.floor(elapsedMs / 1e3);
@@ -3028,11 +3278,61 @@ function computeMinuteRampPollIntervalMs(elapsedMs, params) {
3028
3278
  return Math.min(params.maxIntervalMs, Math.max(params.minIntervalMs, intervalMs));
3029
3279
  }
3030
3280
 
3281
+ // core/decrypt/apiError.ts
3282
+ var BACKEND_ERROR_CODE_TO_COFHE_ERROR_CODE = {
3283
+ bad_request: "BAD_REQUEST" /* BadRequest */,
3284
+ unknown_chain: "UNKNOWN_CHAIN" /* UnknownChain */,
3285
+ acp_malformed: "ACP_MALFORMED" /* ACPMalformed */,
3286
+ acp_denied: "ACP_DENIED" /* ACPDenied */,
3287
+ // ACP-era backends fold revoked into denied
3288
+ acp_expired: "ACP_EXPIRED" /* ACPExpired */,
3289
+ acp_invalid: "ACP_INVALID" /* ACPInvalid */,
3290
+ acp_required: "ACP_REQUIRED" /* ACPRequired */,
3291
+ acp_verifier_error: "ACP_VERIFIER_ERROR" /* ACPVerifierError */,
3292
+ acp_verifier_timeout: "ACP_VERIFIER_TIMEOUT" /* ACPVerifierTimeout */,
3293
+ not_publicly_allowed: "NOT_PUBLICLY_ALLOWED" /* NotPubliclyAllowed */,
3294
+ ct_not_found: "CT_NOT_FOUND" /* CtNotFound */,
3295
+ unsupported_security_zone: "UNSUPPORTED_SECURITY_ZONE" /* UnsupportedSecurityZone */,
3296
+ unsupported_type: "UNSUPPORTED_TYPE" /* UnsupportedType */,
3297
+ internal_error: "INTERNAL_ERROR" /* InternalError */,
3298
+ signing_failed: "SIGNING_FAILED" /* SigningFailed */,
3299
+ ct_source_error: "CT_SOURCE_ERROR" /* CtSourceError */,
3300
+ ct_source_timeout: "CT_SOURCE_TIMEOUT" /* CtSourceTimeout */,
3301
+ seal_failed: "SEAL_FAILED" /* SealFailed */
3302
+ };
3303
+ function isBackendApiErrorCode(value) {
3304
+ return value in BACKEND_ERROR_CODE_TO_COFHE_ERROR_CODE;
3305
+ }
3306
+ async function parseApiErrorResponseBody(response) {
3307
+ let errorMessage = `HTTP ${response.status}`;
3308
+ let apiErrorCode;
3309
+ try {
3310
+ const body = await response.json();
3311
+ if (body && typeof body === "object") {
3312
+ const record = body;
3313
+ if (typeof record.error === "string" && record.error.length > 0) {
3314
+ apiErrorCode = record.error;
3315
+ }
3316
+ if (typeof record.error_message === "string" && record.error_message.length > 0) {
3317
+ errorMessage = record.error_message;
3318
+ } else if (typeof record.message === "string" && record.message.length > 0) {
3319
+ errorMessage = record.message;
3320
+ }
3321
+ }
3322
+ } catch {
3323
+ errorMessage = response.statusText || errorMessage;
3324
+ }
3325
+ return { apiErrorCode, errorMessage };
3326
+ }
3327
+ function mapApiErrorCodeToCofheErrorCode(apiErrorCode, fallback) {
3328
+ if (apiErrorCode && isBackendApiErrorCode(apiErrorCode)) {
3329
+ return BACKEND_ERROR_CODE_TO_COFHE_ERROR_CODE[apiErrorCode];
3330
+ }
3331
+ return fallback;
3332
+ }
3333
+
3031
3334
  // core/decrypt/submitRetry.ts
3032
3335
  var DEFAULT_404_RETRY_TIMEOUT_MS = 1e4;
3033
- function isRetryableSubmitStatus(status) {
3034
- return status === 204 || status === 404;
3035
- }
3036
3336
  function normalize404RetryTimeoutMs(params) {
3037
3337
  const { timeoutMs, operationLabel, errorCode } = params;
3038
3338
  if (timeoutMs === void 0)
@@ -3049,32 +3349,24 @@ function normalize404RetryTimeoutMs(params) {
3049
3349
  return timeoutMs;
3050
3350
  }
3051
3351
  async function classifySubmitResponse(params) {
3052
- const { response, extractErrorMessage } = params;
3053
- if (isRetryableSubmitStatus(response.status)) {
3054
- return { kind: "retryable", status: response.status };
3352
+ const { response, fallbackErrorCode } = params;
3353
+ if (response.status === 204) {
3354
+ return { kind: "retryable", status: 204 };
3055
3355
  }
3056
3356
  if (response.ok) {
3057
3357
  return { kind: "parse-json" };
3058
3358
  }
3059
- let errorMessage = `HTTP ${response.status}`;
3060
- try {
3061
- const errorBody = await response.json();
3062
- const maybeErrorMessage = extractErrorMessage?.(errorBody);
3063
- if (typeof maybeErrorMessage === "string" && maybeErrorMessage.length > 0) {
3064
- errorMessage = maybeErrorMessage;
3065
- } else if (errorBody && typeof errorBody === "object") {
3066
- const defaultMessage = errorBody.error_message;
3067
- const fallbackMessage = errorBody.message;
3068
- if (typeof defaultMessage === "string" && defaultMessage.length > 0) {
3069
- errorMessage = defaultMessage;
3070
- } else if (typeof fallbackMessage === "string" && fallbackMessage.length > 0) {
3071
- errorMessage = fallbackMessage;
3072
- }
3073
- }
3074
- } catch {
3075
- errorMessage = response.statusText || errorMessage;
3359
+ const { apiErrorCode, errorMessage } = await parseApiErrorResponseBody(response);
3360
+ if (response.status === 404) {
3361
+ return { kind: "retryable", status: 404, apiErrorMessage: errorMessage };
3076
3362
  }
3077
- return { kind: "fatal-http", errorMessage };
3363
+ return {
3364
+ kind: "fatal-http",
3365
+ status: response.status,
3366
+ cofheErrorCode: mapApiErrorCodeToCofheErrorCode(apiErrorCode, fallbackErrorCode),
3367
+ apiErrorCode,
3368
+ errorMessage
3369
+ };
3078
3370
  }
3079
3371
  function throwIfSubmitRetryTimedOut(params) {
3080
3372
  const {
@@ -3086,12 +3378,14 @@ function throwIfSubmitRetryTimedOut(params) {
3086
3378
  overallTimeoutMs,
3087
3379
  thresholdNetworkUrl,
3088
3380
  body,
3089
- attemptIndex
3381
+ attemptIndex,
3382
+ lastKnownErrorMessage
3090
3383
  } = params;
3091
3384
  if (status === 404 && elapsedMs > retry404TimeoutMs) {
3092
3385
  throw new CofheError({
3093
- code: errorCode,
3094
- message: `${operationLabel} submit retried 404 responses without receiving request_id for ${retry404TimeoutMs}ms`,
3386
+ code: "CT_NOT_FOUND" /* CtNotFound */,
3387
+ apiErrorCode: "ct_not_found",
3388
+ message: `${operationLabel} ciphertext not found after retrying for ${retry404TimeoutMs}ms` + (lastKnownErrorMessage ? `: ${lastKnownErrorMessage}` : ""),
3095
3389
  hint: "The ciphertext may not be indexed yet. Increase set404RetryTimeout(...) if the backend is slow to index ciphertexts.",
3096
3390
  context: {
3097
3391
  thresholdNetworkUrl,
@@ -3117,6 +3411,62 @@ function throwIfSubmitRetryTimedOut(params) {
3117
3411
  });
3118
3412
  }
3119
3413
  }
3414
+ function normalizeTnSignature(signature) {
3415
+ if (typeof signature !== "string") {
3416
+ throw new CofheError({
3417
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3418
+ message: "decrypt response missing signature",
3419
+ context: {
3420
+ signature
3421
+ }
3422
+ });
3423
+ }
3424
+ const trimmed = signature.trim();
3425
+ if (trimmed.length === 0) {
3426
+ throw new CofheError({
3427
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3428
+ message: "decrypt response returned empty signature"
3429
+ });
3430
+ }
3431
+ const prefixed = trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`;
3432
+ const parsed = viem.parseSignature(prefixed);
3433
+ return viem.serializeSignature(parsed);
3434
+ }
3435
+ function parseDecryptedBytesToBigInt(decrypted) {
3436
+ if (!Array.isArray(decrypted)) {
3437
+ throw new CofheError({
3438
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3439
+ message: "decrypt response field <decrypted> must be a byte array",
3440
+ context: {
3441
+ decrypted
3442
+ }
3443
+ });
3444
+ }
3445
+ if (decrypted.length === 0) {
3446
+ throw new CofheError({
3447
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3448
+ message: "decrypt response field <decrypted> was an empty byte array",
3449
+ context: {
3450
+ decrypted
3451
+ }
3452
+ });
3453
+ }
3454
+ let hex = "";
3455
+ for (const b of decrypted) {
3456
+ if (typeof b !== "number" || !Number.isInteger(b) || b < 0 || b > 255) {
3457
+ throw new CofheError({
3458
+ code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3459
+ message: "decrypt response field <decrypted> contained a non-byte value",
3460
+ context: {
3461
+ badElement: b,
3462
+ decrypted
3463
+ }
3464
+ });
3465
+ }
3466
+ hex += b.toString(16).padStart(2, "0");
3467
+ }
3468
+ return BigInt(`0x${hex}`);
3469
+ }
3120
3470
 
3121
3471
  // core/decrypt/tnSealOutputV2.ts
3122
3472
  var POLL_INTERVAL_MS = 1e3;
@@ -3179,23 +3529,28 @@ function parseCompletedSealOutputResponse(params) {
3179
3529
  }
3180
3530
  return convertSealedData(sealed);
3181
3531
  }
3182
- async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, retry404TimeoutMs, onPoll) {
3532
+ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, onPoll) {
3183
3533
  const body = {
3184
3534
  ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
3185
3535
  host_chain_id: chainId,
3186
- permit: permission
3536
+ acp
3187
3537
  };
3188
3538
  let attemptIndex = 0;
3539
+ let last404ApiErrorMessage;
3189
3540
  for (; ; ) {
3190
3541
  let response;
3191
3542
  try {
3192
- response = await fetch(`${thresholdNetworkUrl}/v2/sealoutput`, {
3193
- method: "POST",
3194
- headers: {
3195
- "Content-Type": "application/json"
3196
- },
3197
- body: JSON.stringify(body)
3198
- });
3543
+ response = await cofheFetch(
3544
+ `${thresholdNetworkUrl}/v2/sealoutput`,
3545
+ /*op:sealoutput*/
3546
+ {
3547
+ method: "POST",
3548
+ headers: {
3549
+ "Content-Type": "application/json"
3550
+ },
3551
+ body: JSON.stringify(body)
3552
+ }
3553
+ );
3199
3554
  } catch (e) {
3200
3555
  throw new CofheError({
3201
3556
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
@@ -3209,16 +3564,19 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
3209
3564
  }
3210
3565
  });
3211
3566
  }
3212
- const responseClassification = await classifySubmitResponse({ response });
3567
+ const responseClassification = await classifySubmitResponse({
3568
+ response,
3569
+ fallbackErrorCode: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */
3570
+ });
3213
3571
  if (responseClassification.kind === "fatal-http") {
3214
3572
  throw new CofheError({
3215
- code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
3573
+ code: responseClassification.cofheErrorCode,
3574
+ apiErrorCode: responseClassification.apiErrorCode,
3216
3575
  message: `sealOutput request failed: ${responseClassification.errorMessage}`,
3217
3576
  hint: "Check the threshold network URL and request parameters.",
3218
3577
  context: {
3219
3578
  thresholdNetworkUrl,
3220
- status: response.status,
3221
- statusText: response.statusText,
3579
+ status: responseClassification.status,
3222
3580
  body,
3223
3581
  attemptIndex
3224
3582
  }
@@ -3264,6 +3622,9 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
3264
3622
  }
3265
3623
  });
3266
3624
  }
3625
+ if (responseClassification.status === 404) {
3626
+ last404ApiErrorMessage = responseClassification.apiErrorMessage;
3627
+ }
3267
3628
  const elapsedMs = Date.now() - overallStartTime;
3268
3629
  throwIfSubmitRetryTimedOut({
3269
3630
  operationLabel: "sealOutput",
@@ -3274,7 +3635,8 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, per
3274
3635
  overallTimeoutMs: SEAL_OUTPUT_TIMEOUT_MS,
3275
3636
  thresholdNetworkUrl,
3276
3637
  body,
3277
- attemptIndex
3638
+ attemptIndex,
3639
+ lastKnownErrorMessage: last404ApiErrorMessage
3278
3640
  });
3279
3641
  onPoll?.({
3280
3642
  operation: "sealoutput",
@@ -3318,12 +3680,16 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
3318
3680
  }
3319
3681
  let response;
3320
3682
  try {
3321
- response = await fetch(`${thresholdNetworkUrl}/v2/sealoutput/${requestId}`, {
3322
- method: "GET",
3323
- headers: {
3324
- "Content-Type": "application/json"
3683
+ response = await cofheFetch(
3684
+ `${thresholdNetworkUrl}/v2/sealoutput/${requestId}`,
3685
+ /*op:sealoutput-poll*/
3686
+ {
3687
+ method: "GET",
3688
+ headers: {
3689
+ "Content-Type": "application/json"
3690
+ }
3325
3691
  }
3326
- });
3692
+ );
3327
3693
  } catch (e) {
3328
3694
  throw new CofheError({
3329
3695
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
@@ -3348,15 +3714,10 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
3348
3714
  });
3349
3715
  }
3350
3716
  if (!response.ok) {
3351
- let errorMessage = `HTTP ${response.status}`;
3352
- try {
3353
- const errorBody = await response.json();
3354
- errorMessage = errorBody.error_message || errorBody.message || errorMessage;
3355
- } catch {
3356
- errorMessage = response.statusText || errorMessage;
3357
- }
3717
+ const { apiErrorCode, errorMessage } = await parseApiErrorResponseBody(response);
3358
3718
  throw new CofheError({
3359
- code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
3719
+ code: mapApiErrorCodeToCofheErrorCode(apiErrorCode, "SEAL_OUTPUT_FAILED" /* SealOutputFailed */),
3720
+ apiErrorCode,
3360
3721
  message: `sealOutput status poll failed: ${errorMessage}`,
3361
3722
  context: {
3362
3723
  thresholdNetworkUrl,
@@ -3400,7 +3761,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
3400
3761
  });
3401
3762
  }
3402
3763
  async function tnSealOutputV2(params) {
3403
- const { thresholdNetworkUrl, ctHash, chainId, permission, retry404TimeoutMs, onPoll } = params;
3764
+ const { thresholdNetworkUrl, ctHash, chainId, acp, retry404TimeoutMs, onPoll } = params;
3404
3765
  const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
3405
3766
  timeoutMs: retry404TimeoutMs,
3406
3767
  operationLabel: "sealOutput",
@@ -3411,7 +3772,7 @@ async function tnSealOutputV2(params) {
3411
3772
  thresholdNetworkUrl,
3412
3773
  ctHash,
3413
3774
  chainId,
3414
- permission,
3775
+ acp,
3415
3776
  overallStartTime,
3416
3777
  normalized404RetryTimeoutMs,
3417
3778
  onPoll
@@ -3427,8 +3788,8 @@ var DEFAULT_404_RETRY_TIMEOUT_MS2 = 1e4;
3427
3788
  var DecryptForViewBuilder = class extends BaseBuilder {
3428
3789
  ctHash;
3429
3790
  utype;
3430
- permitHash;
3431
- permit;
3791
+ acpHash;
3792
+ acp;
3432
3793
  pollCallback;
3433
3794
  retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS2;
3434
3795
  constructor(params) {
@@ -3442,11 +3803,11 @@ var DecryptForViewBuilder = class extends BaseBuilder {
3442
3803
  });
3443
3804
  this.ctHash = params.ctHash;
3444
3805
  this.utype = params.utype;
3445
- this.permitHash = params.permitHash;
3446
- this.permit = params.permit;
3806
+ this.acpHash = params.acpHash;
3807
+ this.acp = params.acp;
3447
3808
  }
3448
3809
  /**
3449
- * @param chainId - Chain to decrypt values from. Used to fetch the threshold network URL and use the correct permit.
3810
+ * @param chainId - Chain to decrypt values from. Used to fetch the threshold network URL and use the correct acp.
3450
3811
  *
3451
3812
  * If not provided, the chainId will be fetched from the connected publicClient.
3452
3813
  *
@@ -3467,7 +3828,7 @@ var DecryptForViewBuilder = class extends BaseBuilder {
3467
3828
  return this.chainId;
3468
3829
  }
3469
3830
  /**
3470
- * @param account - Account to decrypt values from. Used to fetch the correct permit.
3831
+ * @param account - Account to decrypt values from. Used to fetch the correct acp.
3471
3832
  *
3472
3833
  * If not provided, the account will be fetched from the connected walletClient.
3473
3834
  *
@@ -3504,61 +3865,61 @@ var DecryptForViewBuilder = class extends BaseBuilder {
3504
3865
  this.retry404TimeoutMs = timeoutMs;
3505
3866
  return this;
3506
3867
  }
3507
- withPermit(permitOrPermitHash) {
3508
- if (typeof permitOrPermitHash === "string") {
3509
- this.permitHash = permitOrPermitHash;
3510
- this.permit = void 0;
3511
- } else if (permitOrPermitHash === void 0) {
3512
- this.permitHash = void 0;
3513
- this.permit = void 0;
3868
+ withACP(acpOrACPHash) {
3869
+ if (typeof acpOrACPHash === "string") {
3870
+ this.acpHash = acpOrACPHash;
3871
+ this.acp = void 0;
3872
+ } else if (acpOrACPHash === void 0) {
3873
+ this.acpHash = void 0;
3874
+ this.acp = void 0;
3514
3875
  } else {
3515
- this.permit = permitOrPermitHash;
3516
- this.permitHash = void 0;
3876
+ this.acp = acpOrACPHash;
3877
+ this.acpHash = void 0;
3517
3878
  }
3518
3879
  return this;
3519
3880
  }
3520
3881
  /**
3521
- * @param permitHash - Permit hash to decrypt values from. Used to fetch the correct permit.
3882
+ * @param acpHash - ACP hash to decrypt values from. Used to fetch the correct acp.
3522
3883
  *
3523
- * If not provided, the active permit for the chainId and account will be used.
3524
- * If `setPermit()` is called, it will be used regardless of chainId, account, or permitHash.
3884
+ * If not provided, the active acp for the chainId and account will be used.
3885
+ * If `setACP()` is called, it will be used regardless of chainId, account, or acpHash.
3525
3886
  *
3526
3887
  * Example:
3527
3888
  * ```typescript
3528
3889
  * const unsealed = await client.decryptForView(ctHash, utype)
3529
- * .setPermitHash('0x1234567890123456789012345678901234567890')
3890
+ * .setACPHash('0x1234567890123456789012345678901234567890')
3530
3891
  * .execute();
3531
3892
  * ```
3532
3893
  *
3533
3894
  * @returns The chainable DecryptForViewBuilder instance.
3534
3895
  */
3535
- /** @deprecated Use `withPermit(permitHash)` instead. */
3536
- setPermitHash(permitHash) {
3537
- return this.withPermit(permitHash);
3896
+ /** @deprecated Use `withACP(acpHash)` instead. */
3897
+ setACPHash(acpHash) {
3898
+ return this.withACP(acpHash);
3538
3899
  }
3539
- getPermitHash() {
3540
- return this.permitHash;
3900
+ getACPHash() {
3901
+ return this.acpHash;
3541
3902
  }
3542
3903
  /**
3543
- * @param permit - Permit to decrypt values with. If provided, it will be used regardless of chainId, account, or permitHash.
3904
+ * @param acp - ACP to decrypt values with. If provided, it will be used regardless of chainId, account, or acpHash.
3544
3905
  *
3545
- * If not provided, the permit will be determined by chainId, account, and permitHash.
3906
+ * If not provided, the acp will be determined by chainId, account, and acpHash.
3546
3907
  *
3547
3908
  * Example:
3548
3909
  * ```typescript
3549
3910
  * const unsealed = await client.decryptForView(ctHash, utype)
3550
- * .setPermit(permit)
3911
+ * .setACP(acp)
3551
3912
  * .execute();
3552
3913
  * ```
3553
3914
  *
3554
3915
  * @returns The chainable DecryptForViewBuilder instance.
3555
3916
  */
3556
- /** @deprecated Use `withPermit(permit)` instead. */
3557
- setPermit(permit) {
3558
- return this.withPermit(permit);
3917
+ /** @deprecated Use `withACP(acp)` instead. */
3918
+ setACP(acp) {
3919
+ return this.withACP(acp);
3559
3920
  }
3560
- getPermit() {
3561
- return this.permit;
3921
+ getACP() {
3922
+ return this.acp;
3562
3923
  }
3563
3924
  async getThresholdNetworkUrl() {
3564
3925
  this.assertChainId();
@@ -3574,77 +3935,77 @@ var DecryptForViewBuilder = class extends BaseBuilder {
3574
3935
  }
3575
3936
  });
3576
3937
  }
3577
- async getResolvedPermit() {
3578
- if (this.permit)
3579
- return this.permit;
3938
+ async getResolvedACP() {
3939
+ if (this.acp)
3940
+ return this.acp;
3580
3941
  this.assertChainId();
3581
3942
  this.assertAccount();
3582
- if (this.permitHash) {
3583
- const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
3584
- if (!permit2) {
3943
+ if (this.acpHash) {
3944
+ const acp2 = await acps.getACP(this.chainId, this.account, this.acpHash);
3945
+ if (!acp2) {
3585
3946
  throw new CofheError({
3586
- code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
3587
- message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
3588
- hint: "Ensure the permit exists and is valid.",
3947
+ code: "ACP_NOT_FOUND" /* ACPNotFound */,
3948
+ message: `ACP with hash <${this.acpHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
3949
+ hint: "Ensure the acp exists and is valid.",
3589
3950
  context: {
3590
3951
  chainId: this.chainId,
3591
3952
  account: this.account,
3592
- permitHash: this.permitHash
3953
+ acpHash: this.acpHash
3593
3954
  }
3594
3955
  });
3595
3956
  }
3596
- return permit2;
3957
+ return acp2;
3597
3958
  }
3598
- const permit = await permits.getActivePermit(this.chainId, this.account);
3599
- if (!permit) {
3959
+ const acp = await acps.getActiveACP(this.chainId, this.account);
3960
+ if (!acp) {
3600
3961
  throw new CofheError({
3601
- code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
3602
- message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
3603
- hint: "Ensure a permit exists for this account on this chain.",
3962
+ code: "ACP_NOT_FOUND" /* ACPNotFound */,
3963
+ message: `Active acp not found for chainId <${this.chainId}> and account <${this.account}>`,
3964
+ hint: "Ensure an ACP exists for this account on this chain.",
3604
3965
  context: {
3605
3966
  chainId: this.chainId,
3606
3967
  account: this.account
3607
3968
  }
3608
3969
  });
3609
3970
  }
3610
- return permit;
3971
+ return acp;
3611
3972
  }
3612
3973
  /**
3613
3974
  * On hardhat, interact with MockZkVerifier contract instead of CoFHE
3614
3975
  */
3615
- async mocksSealOutput(permit) {
3976
+ async mocksSealOutput(acp) {
3616
3977
  this.assertPublicClient();
3617
3978
  const mocksDecryptDelay = this.config.mocks.decryptDelay;
3618
3979
  if (mocksDecryptDelay > 0)
3619
3980
  await sleep(mocksDecryptDelay);
3620
- return cofheMocksDecryptForView(this.ctHash, this.utype, permit, this.publicClient);
3981
+ return cofheMocksDecryptForView(this.ctHash, this.utype, acp, this.publicClient);
3621
3982
  }
3622
3983
  /**
3623
3984
  * In the production context, perform a true decryption with the CoFHE coprocessor.
3624
3985
  */
3625
- async productionSealOutput(permit) {
3986
+ async productionSealOutput(acp) {
3626
3987
  this.assertChainId();
3627
3988
  this.assertPublicClient();
3628
3989
  const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
3629
- const permission = PermitUtils.getPermission(permit, true);
3990
+ const wireAcp = ACPUtils.getPublic(acp, true);
3630
3991
  const sealed = await tnSealOutputV2({
3631
3992
  ctHash: this.ctHash,
3632
3993
  chainId: this.chainId,
3633
- permission,
3994
+ acp: wireAcp,
3634
3995
  thresholdNetworkUrl,
3635
3996
  retry404TimeoutMs: this.retry404TimeoutMs,
3636
3997
  onPoll: this.pollCallback
3637
3998
  });
3638
- return PermitUtils.unseal(permit, sealed);
3999
+ return ACPUtils.unseal(acp, sealed);
3639
4000
  }
3640
4001
  /**
3641
4002
  * Final step of the decryption process. MUST BE CALLED LAST IN THE CHAIN.
3642
4003
  *
3643
4004
  * This will:
3644
- * - Use a permit based on provided permit OR chainId + account + permitHash
3645
- * - Check permit validity
3646
- * - Call CoFHE `/sealoutput` with the permit, which returns a sealed (encrypted) item
3647
- * - Unseal the sealed item with the permit
4005
+ * - Use an ACP based on provided acp OR chainId + account + acpHash
4006
+ * - Check acp validity
4007
+ * - Call CoFHE `/sealoutput` with the acp, which returns a sealed (encrypted) item
4008
+ * - Unseal the sealed item with the acp
3648
4009
  * - Return the unsealed item
3649
4010
  *
3650
4011
  * Example:
@@ -3652,7 +4013,7 @@ var DecryptForViewBuilder = class extends BaseBuilder {
3652
4013
  * const unsealed = await client.decryptForView(ctHash, utype)
3653
4014
  * .setChainId(11155111) // optional
3654
4015
  * .setAccount('0x123...890') // optional
3655
- * .withPermit() // optional
4016
+ * .withACP() // optional
3656
4017
  * .execute(); // execute
3657
4018
  * ```
3658
4019
  *
@@ -3660,14 +4021,14 @@ var DecryptForViewBuilder = class extends BaseBuilder {
3660
4021
  */
3661
4022
  async execute() {
3662
4023
  this.validateUtypeOrThrow();
3663
- const permit = await this.getResolvedPermit();
3664
- PermitUtils.validate(permit);
3665
- const chainId = permit._signedDomain.chainId;
4024
+ const acp = await this.getResolvedACP();
4025
+ ACPUtils.validate(acp);
4026
+ const chainId = acp._signedDomain.chainId;
3666
4027
  let unsealed;
3667
4028
  if (chainId === hardhat2.id) {
3668
- unsealed = await this.mocksSealOutput(permit);
4029
+ unsealed = await this.mocksSealOutput(acp);
3669
4030
  } else {
3670
- unsealed = await this.productionSealOutput(permit);
4031
+ unsealed = await this.productionSealOutput(acp);
3671
4032
  }
3672
4033
  return convertViaUtype(this.utype, unsealed);
3673
4034
  }
@@ -3675,28 +4036,28 @@ var DecryptForViewBuilder = class extends BaseBuilder {
3675
4036
  var UINT_TYPE_MASK = 0x7fn;
3676
4037
  var TYPE_BYTE_OFFSET = 8n;
3677
4038
  var getEncryptionTypeFromCtHash = (ctHash) => Number(ctHash >> TYPE_BYTE_OFFSET & UINT_TYPE_MASK);
3678
- async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient) {
4039
+ async function cofheMocksDecryptForTx(ctHash, utype, acp, publicClient) {
3679
4040
  let allowed;
3680
4041
  let error;
3681
4042
  let decryptedValue;
3682
- if (permit !== null) {
3683
- let permission = PermitUtils.getPermission(permit, true);
4043
+ if (acp !== null) {
4044
+ const wireAcp = ACPUtils.getPublic(acp, true);
3684
4045
  const permissionWithBigInts = {
3685
- ...permission,
3686
- expiration: BigInt(permission.expiration),
3687
- validatorId: BigInt(permission.validatorId)
4046
+ ...wireAcp,
4047
+ expiration: BigInt(wireAcp.expiration),
4048
+ revokerData: BigInt(wireAcp.revokerData)
3688
4049
  };
3689
4050
  [allowed, error, decryptedValue] = await publicClient.readContract({
3690
4051
  address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
3691
4052
  abi: MockThresholdNetworkAbi,
3692
- functionName: "decryptForTxWithPermit",
4053
+ functionName: "decryptForTxWithACP",
3693
4054
  args: [BigInt(ctHash), permissionWithBigInts]
3694
4055
  });
3695
4056
  } else {
3696
4057
  [allowed, error, decryptedValue] = await publicClient.readContract({
3697
4058
  address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
3698
4059
  abi: MockThresholdNetworkAbi,
3699
- functionName: "decryptForTxWithoutPermit",
4060
+ functionName: "decryptForTxWithoutACP",
3700
4061
  args: [BigInt(ctHash)]
3701
4062
  });
3702
4063
  }
@@ -3731,62 +4092,6 @@ async function cofheMocksDecryptForTx(ctHash, utype, permit, publicClient) {
3731
4092
  signature
3732
4093
  };
3733
4094
  }
3734
- function normalizeTnSignature(signature) {
3735
- if (typeof signature !== "string") {
3736
- throw new CofheError({
3737
- code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3738
- message: "decrypt response missing signature",
3739
- context: {
3740
- signature
3741
- }
3742
- });
3743
- }
3744
- const trimmed = signature.trim();
3745
- if (trimmed.length === 0) {
3746
- throw new CofheError({
3747
- code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3748
- message: "decrypt response returned empty signature"
3749
- });
3750
- }
3751
- const prefixed = trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`;
3752
- const parsed = viem.parseSignature(prefixed);
3753
- return viem.serializeSignature(parsed);
3754
- }
3755
- function parseDecryptedBytesToBigInt(decrypted) {
3756
- if (!Array.isArray(decrypted)) {
3757
- throw new CofheError({
3758
- code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3759
- message: "decrypt response field <decrypted> must be a byte array",
3760
- context: {
3761
- decrypted
3762
- }
3763
- });
3764
- }
3765
- if (decrypted.length === 0) {
3766
- throw new CofheError({
3767
- code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3768
- message: "decrypt response field <decrypted> was an empty byte array",
3769
- context: {
3770
- decrypted
3771
- }
3772
- });
3773
- }
3774
- let hex = "";
3775
- for (const b of decrypted) {
3776
- if (typeof b !== "number" || !Number.isInteger(b) || b < 0 || b > 255) {
3777
- throw new CofheError({
3778
- code: "DECRYPT_RETURNED_NULL" /* DecryptReturnedNull */,
3779
- message: "decrypt response field <decrypted> contained a non-byte value",
3780
- context: {
3781
- badElement: b,
3782
- decrypted
3783
- }
3784
- });
3785
- }
3786
- hex += b.toString(16).padStart(2, "0");
3787
- }
3788
- return BigInt(`0x${hex}`);
3789
- }
3790
4095
 
3791
4096
  // core/decrypt/tnDecryptV2.ts
3792
4097
  var POLL_INTERVAL_MS2 = 1e3;
@@ -3908,25 +4213,30 @@ function assertDecryptStatusResponseV2(value) {
3908
4213
  }
3909
4214
  return value;
3910
4215
  }
3911
- async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission, overallStartTime, retry404TimeoutMs, onPoll) {
4216
+ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, onPoll) {
3912
4217
  const body = {
3913
4218
  ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
3914
4219
  host_chain_id: chainId
3915
4220
  };
3916
- if (permission) {
3917
- body.permit = permission;
4221
+ if (acp) {
4222
+ body.acp = acp;
3918
4223
  }
3919
4224
  let attemptIndex = 0;
4225
+ let last404ApiErrorMessage;
3920
4226
  for (; ; ) {
3921
4227
  let response;
3922
4228
  try {
3923
- response = await fetch(`${thresholdNetworkUrl}/v2/decrypt`, {
3924
- method: "POST",
3925
- headers: {
3926
- "Content-Type": "application/json"
3927
- },
3928
- body: JSON.stringify(body)
3929
- });
4229
+ response = await cofheFetch(
4230
+ `${thresholdNetworkUrl}/v2/decrypt`,
4231
+ /*op:decrypt*/
4232
+ {
4233
+ method: "POST",
4234
+ headers: {
4235
+ "Content-Type": "application/json"
4236
+ },
4237
+ body: JSON.stringify(body)
4238
+ }
4239
+ );
3930
4240
  } catch (e) {
3931
4241
  throw new CofheError({
3932
4242
  code: "DECRYPT_FAILED" /* DecryptFailed */,
@@ -3940,16 +4250,19 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
3940
4250
  }
3941
4251
  });
3942
4252
  }
3943
- const responseClassification = await classifySubmitResponse({ response });
4253
+ const responseClassification = await classifySubmitResponse({
4254
+ response,
4255
+ fallbackErrorCode: "DECRYPT_FAILED" /* DecryptFailed */
4256
+ });
3944
4257
  if (responseClassification.kind === "fatal-http") {
3945
4258
  throw new CofheError({
3946
- code: "DECRYPT_FAILED" /* DecryptFailed */,
4259
+ code: responseClassification.cofheErrorCode,
4260
+ apiErrorCode: responseClassification.apiErrorCode,
3947
4261
  message: `decrypt request failed: ${responseClassification.errorMessage}`,
3948
4262
  hint: "Check the threshold network URL and request parameters.",
3949
4263
  context: {
3950
4264
  thresholdNetworkUrl,
3951
- status: response.status,
3952
- statusText: response.statusText,
4265
+ status: responseClassification.status,
3953
4266
  body,
3954
4267
  attemptIndex
3955
4268
  }
@@ -3997,6 +4310,9 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
3997
4310
  }
3998
4311
  });
3999
4312
  }
4313
+ if (responseClassification.status === 404) {
4314
+ last404ApiErrorMessage = responseClassification.apiErrorMessage;
4315
+ }
4000
4316
  const elapsedMs = Date.now() - overallStartTime;
4001
4317
  throwIfSubmitRetryTimedOut({
4002
4318
  operationLabel: "decrypt",
@@ -4007,7 +4323,8 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, perm
4007
4323
  overallTimeoutMs: DECRYPT_TIMEOUT_MS,
4008
4324
  thresholdNetworkUrl,
4009
4325
  body,
4010
- attemptIndex
4326
+ attemptIndex,
4327
+ lastKnownErrorMessage: last404ApiErrorMessage
4011
4328
  });
4012
4329
  onPoll?.({
4013
4330
  operation: "decrypt",
@@ -4051,12 +4368,16 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
4051
4368
  }
4052
4369
  let response;
4053
4370
  try {
4054
- response = await fetch(`${thresholdNetworkUrl}/v2/decrypt/${requestId}`, {
4055
- method: "GET",
4056
- headers: {
4057
- "Content-Type": "application/json"
4371
+ response = await cofheFetch(
4372
+ `${thresholdNetworkUrl}/v2/decrypt/${requestId}`,
4373
+ /*op:decrypt-poll*/
4374
+ {
4375
+ method: "GET",
4376
+ headers: {
4377
+ "Content-Type": "application/json"
4378
+ }
4058
4379
  }
4059
- });
4380
+ );
4060
4381
  } catch (e) {
4061
4382
  throw new CofheError({
4062
4383
  code: "DECRYPT_FAILED" /* DecryptFailed */,
@@ -4081,17 +4402,10 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
4081
4402
  });
4082
4403
  }
4083
4404
  if (!response.ok) {
4084
- let errorMessage = `HTTP ${response.status}`;
4085
- try {
4086
- const errorBody = await response.json();
4087
- const maybeMessage = errorBody.error_message || errorBody.message;
4088
- if (typeof maybeMessage === "string" && maybeMessage.length > 0)
4089
- errorMessage = maybeMessage;
4090
- } catch {
4091
- errorMessage = response.statusText || errorMessage;
4092
- }
4405
+ const { apiErrorCode, errorMessage } = await parseApiErrorResponseBody(response);
4093
4406
  throw new CofheError({
4094
- code: "DECRYPT_FAILED" /* DecryptFailed */,
4407
+ code: mapApiErrorCodeToCofheErrorCode(apiErrorCode, "DECRYPT_FAILED" /* DecryptFailed */),
4408
+ apiErrorCode,
4095
4409
  message: `decrypt status poll failed: ${errorMessage}`,
4096
4410
  context: {
4097
4411
  thresholdNetworkUrl,
@@ -4136,7 +4450,7 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
4136
4450
  });
4137
4451
  }
4138
4452
  async function tnDecryptV2(params) {
4139
- const { thresholdNetworkUrl, ctHash, chainId, permission, retry404TimeoutMs, onPoll } = params;
4453
+ const { thresholdNetworkUrl, ctHash, chainId, acp, retry404TimeoutMs, onPoll } = params;
4140
4454
  const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
4141
4455
  timeoutMs: retry404TimeoutMs,
4142
4456
  operationLabel: "decrypt",
@@ -4147,7 +4461,7 @@ async function tnDecryptV2(params) {
4147
4461
  thresholdNetworkUrl,
4148
4462
  ctHash,
4149
4463
  chainId,
4150
- permission,
4464
+ acp,
4151
4465
  overallStartTime,
4152
4466
  normalized404RetryTimeoutMs,
4153
4467
  onPoll
@@ -4162,9 +4476,9 @@ async function tnDecryptV2(params) {
4162
4476
  var DEFAULT_404_RETRY_TIMEOUT_MS3 = 1e4;
4163
4477
  var DecryptForTxBuilder = class extends BaseBuilder {
4164
4478
  ctHash;
4165
- permitHash;
4166
- permit;
4167
- permitSelection = "unset";
4479
+ acpHash;
4480
+ acp;
4481
+ acpSelection = "unset";
4168
4482
  pollCallback;
4169
4483
  retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS3;
4170
4484
  constructor(params) {
@@ -4209,137 +4523,137 @@ var DecryptForTxBuilder = class extends BaseBuilder {
4209
4523
  this.retry404TimeoutMs = timeoutMs;
4210
4524
  return this;
4211
4525
  }
4212
- withPermit(permitOrPermitHash) {
4213
- if (this.permitSelection === "with-permit") {
4526
+ withACP(acpOrACPHash) {
4527
+ if (this.acpSelection === "with-acp") {
4214
4528
  throw new CofheError({
4215
4529
  code: "INTERNAL_ERROR" /* InternalError */,
4216
- message: "decryptForTx: withPermit() can only be selected once.",
4217
- hint: "Choose the permit mode once. If you need a different permit, start a new decryptForTx() builder chain."
4530
+ message: "decryptForTx: withACP() can only be selected once.",
4531
+ hint: "Choose the acp mode once. If you need a different acp, start a new decryptForTx() builder chain."
4218
4532
  });
4219
4533
  }
4220
- if (this.permitSelection === "without-permit") {
4534
+ if (this.acpSelection === "without-acp") {
4221
4535
  throw new CofheError({
4222
4536
  code: "INTERNAL_ERROR" /* InternalError */,
4223
- message: "decryptForTx: cannot call withPermit() after withoutPermit() has been selected.",
4224
- hint: "Choose exactly one permit mode: either call .withPermit(...) or .withoutPermit(), but not both."
4537
+ message: "decryptForTx: cannot call withACP() after withoutACP() has been selected.",
4538
+ hint: "Choose exactly one acp mode: either call .withACP(...) or .withoutACP(), but not both."
4225
4539
  });
4226
4540
  }
4227
- this.permitSelection = "with-permit";
4228
- if (typeof permitOrPermitHash === "string") {
4229
- this.permitHash = permitOrPermitHash;
4230
- this.permit = void 0;
4231
- } else if (permitOrPermitHash === void 0) {
4232
- this.permitHash = void 0;
4233
- this.permit = void 0;
4541
+ this.acpSelection = "with-acp";
4542
+ if (typeof acpOrACPHash === "string") {
4543
+ this.acpHash = acpOrACPHash;
4544
+ this.acp = void 0;
4545
+ } else if (acpOrACPHash === void 0) {
4546
+ this.acpHash = void 0;
4547
+ this.acp = void 0;
4234
4548
  } else {
4235
- this.permit = permitOrPermitHash;
4236
- this.permitHash = void 0;
4549
+ this.acp = acpOrACPHash;
4550
+ this.acpHash = void 0;
4237
4551
  }
4238
4552
  return this;
4239
4553
  }
4240
4554
  /**
4241
- * Select "no permit" mode.
4555
+ * Select "no acp" mode.
4242
4556
  *
4243
- * This uses global allowance (no permit required) and sends an empty permission payload to `/decrypt`.
4557
+ * This uses global allowance (no acp required) and sends an empty permission payload to `/decrypt`.
4244
4558
  */
4245
- withoutPermit() {
4246
- if (this.permitSelection === "without-permit") {
4559
+ withoutACP() {
4560
+ if (this.acpSelection === "without-acp") {
4247
4561
  throw new CofheError({
4248
4562
  code: "INTERNAL_ERROR" /* InternalError */,
4249
- message: "decryptForTx: withoutPermit() can only be selected once.",
4250
- hint: "Choose the permit mode once. If you need a different mode, start a new decryptForTx() builder chain."
4563
+ message: "decryptForTx: withoutACP() can only be selected once.",
4564
+ hint: "Choose the acp mode once. If you need a different mode, start a new decryptForTx() builder chain."
4251
4565
  });
4252
4566
  }
4253
- if (this.permitSelection === "with-permit") {
4567
+ if (this.acpSelection === "with-acp") {
4254
4568
  throw new CofheError({
4255
4569
  code: "INTERNAL_ERROR" /* InternalError */,
4256
- message: "decryptForTx: cannot call withoutPermit() after withPermit() has been selected.",
4257
- hint: "Choose exactly one permit mode: either call .withPermit(...) or .withoutPermit(), but not both."
4570
+ message: "decryptForTx: cannot call withoutACP() after withACP() has been selected.",
4571
+ hint: "Choose exactly one acp mode: either call .withACP(...) or .withoutACP(), but not both."
4258
4572
  });
4259
4573
  }
4260
- this.permitSelection = "without-permit";
4261
- this.permitHash = void 0;
4262
- this.permit = void 0;
4574
+ this.acpSelection = "without-acp";
4575
+ this.acpHash = void 0;
4576
+ this.acp = void 0;
4263
4577
  return this;
4264
4578
  }
4265
- getPermit() {
4266
- return this.permit;
4579
+ getACP() {
4580
+ return this.acp;
4267
4581
  }
4268
- getPermitHash() {
4269
- return this.permitHash;
4582
+ getACPHash() {
4583
+ return this.acpHash;
4270
4584
  }
4271
4585
  async getThresholdNetworkUrl() {
4272
4586
  this.assertChainId();
4273
4587
  return getThresholdNetworkUrlOrThrow(this.config, this.chainId);
4274
4588
  }
4275
- async getResolvedPermit() {
4276
- if (this.permitSelection === "unset") {
4589
+ async getResolvedACP() {
4590
+ if (this.acpSelection === "unset") {
4277
4591
  throw new CofheError({
4278
4592
  code: "INTERNAL_ERROR" /* InternalError */,
4279
- message: "decryptForTx: missing permit selection; call withPermit(...) or withoutPermit() before execute().",
4280
- hint: "Call .withPermit() to use the active permit, or .withoutPermit() for global allowance."
4593
+ message: "decryptForTx: missing acp selection; call withACP(...) or withoutACP() before execute().",
4594
+ hint: "Call .withACP() to use the active acp, or .withoutACP() for global allowance."
4281
4595
  });
4282
4596
  }
4283
- if (this.permitSelection === "without-permit") {
4597
+ if (this.acpSelection === "without-acp") {
4284
4598
  return null;
4285
4599
  }
4286
- if (this.permit)
4287
- return this.permit;
4600
+ if (this.acp)
4601
+ return this.acp;
4288
4602
  this.assertChainId();
4289
4603
  this.assertAccount();
4290
- if (this.permitHash) {
4291
- const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
4292
- if (!permit2) {
4604
+ if (this.acpHash) {
4605
+ const acp2 = await acps.getACP(this.chainId, this.account, this.acpHash);
4606
+ if (!acp2) {
4293
4607
  throw new CofheError({
4294
- code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
4295
- message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
4296
- hint: "Ensure the permit exists and is valid.",
4608
+ code: "ACP_NOT_FOUND" /* ACPNotFound */,
4609
+ message: `ACP with hash <${this.acpHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
4610
+ hint: "Ensure the acp exists and is valid.",
4297
4611
  context: {
4298
4612
  chainId: this.chainId,
4299
4613
  account: this.account,
4300
- permitHash: this.permitHash
4614
+ acpHash: this.acpHash
4301
4615
  }
4302
4616
  });
4303
4617
  }
4304
- return permit2;
4618
+ return acp2;
4305
4619
  }
4306
- const permit = await permits.getActivePermit(this.chainId, this.account);
4307
- if (!permit) {
4620
+ const acp = await acps.getActiveACP(this.chainId, this.account);
4621
+ if (!acp) {
4308
4622
  throw new CofheError({
4309
- code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
4310
- message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
4311
- hint: "Create a permit (e.g. client.permits.createSelf(...)) and/or set it active (client.permits.selectActivePermit(hash)).",
4623
+ code: "ACP_NOT_FOUND" /* ACPNotFound */,
4624
+ message: `Active acp not found for chainId <${this.chainId}> and account <${this.account}>`,
4625
+ hint: "Create an ACP (e.g. client.acp.createSelf(...)) and/or set it active (client.acp.selectActiveACP(hash)).",
4312
4626
  context: {
4313
4627
  chainId: this.chainId,
4314
4628
  account: this.account
4315
4629
  }
4316
4630
  });
4317
4631
  }
4318
- return permit;
4632
+ return acp;
4319
4633
  }
4320
4634
  /**
4321
4635
  * On hardhat, interact with MockThresholdNetwork contract
4322
4636
  */
4323
- async mocksDecryptForTx(permit) {
4637
+ async mocksDecryptForTx(acp) {
4324
4638
  this.assertPublicClient();
4325
4639
  const delay = this.config.mocks.decryptDelay;
4326
4640
  if (delay > 0)
4327
4641
  await sleep(delay);
4328
- const result = await cofheMocksDecryptForTx(this.ctHash, 0, permit, this.publicClient);
4642
+ const result = await cofheMocksDecryptForTx(this.ctHash, 0, acp, this.publicClient);
4329
4643
  return result;
4330
4644
  }
4331
4645
  /**
4332
4646
  * In the production context, perform a true decryption with the CoFHE coprocessor.
4333
4647
  */
4334
- async productionDecryptForTx(permit) {
4648
+ async productionDecryptForTx(acp) {
4335
4649
  this.assertChainId();
4336
4650
  this.assertPublicClient();
4337
4651
  const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
4338
- const permission = permit ? PermitUtils.getPermission(permit, true) : null;
4652
+ const wireAcp = acp ? ACPUtils.getPublic(acp, true) : null;
4339
4653
  const { decryptedValue, signature } = await tnDecryptV2({
4340
4654
  ctHash: this.ctHash,
4341
4655
  chainId: this.chainId,
4342
- permission,
4656
+ acp: wireAcp,
4343
4657
  thresholdNetworkUrl,
4344
4658
  retry404TimeoutMs: this.retry404TimeoutMs,
4345
4659
  onPoll: this.pollCallback
@@ -4353,19 +4667,19 @@ var DecryptForTxBuilder = class extends BaseBuilder {
4353
4667
  /**
4354
4668
  * Final step of the decryptForTx process. MUST BE CALLED LAST IN THE CHAIN.
4355
4669
  *
4356
- * You must explicitly choose one permit mode before calling `execute()`:
4357
- * - `withPermit(permit)` / `withPermit(permitHash)` / `withPermit()` (active permit)
4358
- * - `withoutPermit()` (global allowance)
4670
+ * You must explicitly choose one acp mode before calling `execute()`:
4671
+ * - `withACP(acp)` / `withACP(acpHash)` / `withACP()` (active acp)
4672
+ * - `withoutACP()` (global allowance)
4359
4673
  */
4360
4674
  async execute() {
4361
- const permit = await this.getResolvedPermit();
4362
- if (permit !== null) {
4363
- PermitUtils.validate(permit);
4364
- const chainId = permit._signedDomain.chainId;
4675
+ const acp = await this.getResolvedACP();
4676
+ if (acp !== null) {
4677
+ ACPUtils.validate(acp);
4678
+ const chainId = acp._signedDomain.chainId;
4365
4679
  if (chainId === hardhat2.id) {
4366
- return await this.mocksDecryptForTx(permit);
4680
+ return await this.mocksDecryptForTx(acp);
4367
4681
  } else {
4368
- return await this.productionDecryptForTx(permit);
4682
+ return await this.productionDecryptForTx(acp);
4369
4683
  }
4370
4684
  } else {
4371
4685
  if (!this.chainId) {
@@ -4428,6 +4742,21 @@ function createCofheClientBase(opts) {
4428
4742
  const updateConnectState = (partial) => {
4429
4743
  connectStore.setState((state) => ({ ...state, ...partial }));
4430
4744
  };
4745
+ const _resolveSharingRegistry = async (publicClient, chainId) => {
4746
+ const configured = opts.config.acp?.sharingRegistry?.[chainId];
4747
+ if (configured != null)
4748
+ return configured;
4749
+ const registry = (await acps.getAclServedAddresses(publicClient, chainId)).shareRegistry;
4750
+ if (registry == null) {
4751
+ throw new CofheError({
4752
+ code: "MISSING_CONFIG" /* MissingConfig */,
4753
+ message: `No ACP share registry available for chainId <${chainId}>`,
4754
+ hint: "The ACL on this chain does not serve a share registry address. Set `acp.sharingRegistry` in the cofhe config to use on-chain sharing.",
4755
+ context: { chainId }
4756
+ });
4757
+ }
4758
+ return registry;
4759
+ };
4431
4760
  const _requireConnected = () => {
4432
4761
  const state = connectStore.getState();
4433
4762
  const notConnected = !state.connected || !state.account || !state.chainId || !state.publicClient || !state.walletClient;
@@ -4550,74 +4879,147 @@ function createCofheClientBase(opts) {
4550
4879
  }
4551
4880
  return { chainId: _chainId, account: _account };
4552
4881
  };
4553
- const clientPermits = {
4882
+ const clientACPs = {
4554
4883
  // Pass through store access
4555
- getSnapshot: permits.getSnapshot,
4556
- subscribe: permits.subscribe,
4884
+ getSnapshot: acps.getSnapshot,
4885
+ subscribe: acps.subscribe,
4557
4886
  // Creation methods (require connection)
4558
4887
  createSelf: async (options, clients) => {
4559
4888
  _requireConnected();
4560
4889
  const { publicClient, walletClient } = clients ?? connectStore.getState();
4561
- return permits.createSelf(options, publicClient, walletClient);
4890
+ const chainId = await publicClient.getChainId();
4891
+ return acps.createSelf(
4892
+ await acps.applyACPDefaultsFromChain(options, opts.config.acp, publicClient, chainId),
4893
+ publicClient,
4894
+ walletClient
4895
+ );
4562
4896
  },
4563
4897
  createSharing: async (options, clients) => {
4564
4898
  _requireConnected();
4565
4899
  const { publicClient, walletClient } = clients ?? connectStore.getState();
4566
- return permits.createSharing(options, publicClient, walletClient);
4900
+ const chainId = await publicClient.getChainId();
4901
+ return acps.createSharing(
4902
+ await acps.applyACPDefaultsFromChain(options, opts.config.acp, publicClient, chainId),
4903
+ publicClient,
4904
+ walletClient
4905
+ );
4567
4906
  },
4568
4907
  importShared: async (options, clients) => {
4569
4908
  _requireConnected();
4570
4909
  const { publicClient, walletClient } = clients ?? connectStore.getState();
4571
- return permits.importShared(options, publicClient, walletClient);
4910
+ return acps.importShared(options, publicClient, walletClient);
4572
4911
  },
4573
4912
  // Get or create methods (require connection)
4574
- getOrCreateSelfPermit: async (chainId, account, options) => {
4913
+ getOrCreateSelfACP: async (chainId, account, options) => {
4575
4914
  _requireConnected();
4576
4915
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
4577
4916
  const { publicClient, walletClient } = connectStore.getState();
4578
- return permits.getOrCreateSelfPermit(publicClient, walletClient, _chainId, _account, options);
4917
+ const optionsWithDefaults = await acps.applyACPDefaultsFromChain(
4918
+ options ?? { issuer: _account, name: "Autogenerated Self ACP" },
4919
+ opts.config.acp,
4920
+ publicClient,
4921
+ _chainId
4922
+ );
4923
+ return acps.getOrCreateSelfACP(publicClient, walletClient, _chainId, _account, optionsWithDefaults);
4579
4924
  },
4580
- getOrCreateSharingPermit: async (options, chainId, account) => {
4925
+ getOrCreateSharingACP: async (options, chainId, account) => {
4581
4926
  _requireConnected();
4582
4927
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
4583
4928
  const { publicClient, walletClient } = connectStore.getState();
4584
- return permits.getOrCreateSharingPermit(publicClient, walletClient, options, _chainId, _account);
4929
+ return acps.getOrCreateSharingACP(
4930
+ publicClient,
4931
+ walletClient,
4932
+ await acps.applyACPDefaultsFromChain(options, opts.config.acp, publicClient, _chainId),
4933
+ _chainId,
4934
+ _account
4935
+ );
4936
+ },
4937
+ // Revocation (require connection)
4938
+ revokeACP: async (acp) => {
4939
+ _requireConnected();
4940
+ const { walletClient } = connectStore.getState();
4941
+ return acps.revokeACP(acp, walletClient);
4942
+ },
4943
+ revokeAllACPs: async (revokerContract) => {
4944
+ _requireConnected();
4945
+ const { publicClient, walletClient } = connectStore.getState();
4946
+ return acps.revokeAllACPs(walletClient, publicClient, revokerContract);
4947
+ },
4948
+ isACPRevoked: async (acp) => {
4949
+ _requireConnected();
4950
+ const { publicClient } = connectStore.getState();
4951
+ return acps.isACPRevoked(acp, publicClient);
4952
+ },
4953
+ // On-chain sharing (require connection + config.acp.sharingRegistry)
4954
+ shareOnChain: async (acp) => {
4955
+ _requireConnected();
4956
+ const { publicClient, walletClient } = connectStore.getState();
4957
+ const chainId = await publicClient.getChainId();
4958
+ const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
4959
+ return acps.shareOnChain(acp, walletClient, sharingRegistry);
4960
+ },
4961
+ getIncomingShares: async () => {
4962
+ _requireConnected();
4963
+ const { publicClient, walletClient } = connectStore.getState();
4964
+ const chainId = await publicClient.getChainId();
4965
+ const account = walletClient.account.address;
4966
+ const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
4967
+ return acps.getIncomingShares(publicClient, sharingRegistry, account);
4968
+ },
4969
+ importFromChain: async (share) => {
4970
+ _requireConnected();
4971
+ const { publicClient, walletClient } = connectStore.getState();
4972
+ return acps.importFromChain(share, publicClient, walletClient);
4973
+ },
4974
+ dismissShare: async (shareId) => {
4975
+ _requireConnected();
4976
+ const { publicClient, walletClient } = connectStore.getState();
4977
+ const chainId = await publicClient.getChainId();
4978
+ const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
4979
+ return acps.removeShareOnChain(shareId, walletClient, sharingRegistry);
4980
+ },
4981
+ cancelShare: async (shareId) => {
4982
+ _requireConnected();
4983
+ const { publicClient, walletClient } = connectStore.getState();
4984
+ const chainId = await publicClient.getChainId();
4985
+ const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
4986
+ return acps.removeShareOnChain(shareId, walletClient, sharingRegistry);
4585
4987
  },
4586
4988
  // Retrieval methods (auto-fill chainId/account)
4587
- getPermit: (hash, chainId, account) => {
4989
+ getACP: (hash, chainId, account) => {
4588
4990
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
4589
- return permits.getPermit(_chainId, _account, hash);
4991
+ return acps.getACP(_chainId, _account, hash);
4590
4992
  },
4591
- getPermits: (chainId, account) => {
4993
+ getACPs: (chainId, account) => {
4592
4994
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
4593
- return permits.getPermits(_chainId, _account);
4995
+ return acps.getACPs(_chainId, _account);
4594
4996
  },
4595
- getActivePermit: (chainId, account) => {
4997
+ getActiveACP: (chainId, account) => {
4596
4998
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
4597
- return permits.getActivePermit(_chainId, _account);
4999
+ return acps.getActiveACP(_chainId, _account);
4598
5000
  },
4599
- getActivePermitHash: (chainId, account) => {
5001
+ getActiveACPHash: (chainId, account) => {
4600
5002
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
4601
- return permits.getActivePermitHash(_chainId, _account);
5003
+ return acps.getActiveACPHash(_chainId, _account);
4602
5004
  },
4603
5005
  // Mutation methods (auto-fill chainId/account)
4604
- selectActivePermit: (hash, chainId, account) => {
5006
+ selectActiveACP: (hash, chainId, account) => {
4605
5007
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
4606
- return permits.selectActivePermit(_chainId, _account, hash);
5008
+ return acps.selectActiveACP(_chainId, _account, hash);
4607
5009
  },
4608
- removePermit: async (hash, chainId, account) => {
5010
+ removeACP: async (hash, chainId, account) => {
4609
5011
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
4610
- return permits.removePermit(_chainId, _account, hash);
5012
+ return acps.removeACP(_chainId, _account, hash);
4611
5013
  },
4612
- removeActivePermit: async (chainId, account) => {
5014
+ removeActiveACP: async (chainId, account) => {
4613
5015
  const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
4614
- return permits.removeActivePermit(_chainId, _account);
5016
+ return acps.removeActiveACP(_chainId, _account);
4615
5017
  },
4616
5018
  // Utils (no context needed)
4617
- getHash: permits.getHash,
4618
- export: permits.export,
4619
- serialize: permits.serialize,
4620
- deserialize: permits.deserialize
5019
+ getHash: acps.getHash,
5020
+ export: acps.export,
5021
+ serialize: acps.serialize,
5022
+ deserialize: acps.deserialize
4621
5023
  };
4622
5024
  return {
4623
5025
  // Zustand reactive accessors (don't export store directly to prevent mutation)
@@ -4645,7 +5047,7 @@ function createCofheClientBase(opts) {
4645
5047
  decryptHandle: decryptForView,
4646
5048
  decryptForTx,
4647
5049
  verifyDecryptResult: verifyDecryptResult2,
4648
- permits: clientPermits
5050
+ acp: clientACPs
4649
5051
  // Add SDK-specific methods below that require connection
4650
5052
  // Example:
4651
5053
  // async encryptData(data: unknown) {
@@ -4674,15 +5076,18 @@ exports.MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_
4674
5076
  exports.TASK_MANAGER_ADDRESS = TASK_MANAGER_ADDRESS;
4675
5077
  exports.TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT = TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT;
4676
5078
  exports.TFHE_RS_ZK_MAX_BITS = TFHE_RS_ZK_MAX_BITS;
4677
- exports.assertCorrectEncryptedItemInput = assertCorrectEncryptedItemInput;
5079
+ exports.assertNoRenamedConfigKeys = assertNoRenamedConfigKeys;
5080
+ exports.cofheFetch = cofheFetch;
4678
5081
  exports.createCofheClientBase = createCofheClientBase;
4679
5082
  exports.createCofheConfigBase = createCofheConfigBase;
4680
5083
  exports.createKeysStore = createKeysStore;
4681
5084
  exports.fetchKeys = fetchKeys;
4682
5085
  exports.fheTypeToString = fheTypeToString;
4683
5086
  exports.getCofheConfigItem = getCofheConfigItem;
5087
+ exports.getCofheDebugInterceptors = getCofheDebugInterceptors;
4684
5088
  exports.isCofheError = isCofheError;
4685
5089
  exports.isEncryptableItem = isEncryptableItem;
4686
5090
  exports.isLastEncryptionStep = isLastEncryptionStep;
5091
+ exports.setCofheDebugInterceptors = setCofheDebugInterceptors;
4687
5092
  exports.verifyDecryptResult = verifyDecryptResult;
4688
5093
  exports.zkProveWithWorker = zkProveWithWorker;