@cofhe/sdk 1.0.1 → 1.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +0 -8
  2. package/core/acps.ts +64 -23
  3. package/core/client.ts +32 -1
  4. package/core/clientTypes.ts +22 -1
  5. package/core/decrypt/decryptForTxBuilder.ts +16 -0
  6. package/core/decrypt/decryptForViewBuilder.ts +14 -0
  7. package/core/decrypt/submitRetry.ts +16 -0
  8. package/core/decrypt/tnDecryptV2.ts +19 -9
  9. package/core/decrypt/tnSealOutputV2.ts +19 -9
  10. package/core/encrypt/encryptInputsBuilder.ts +13 -31
  11. package/core/encrypt/zkPackProveVerify.ts +4 -16
  12. package/core/error.ts +0 -1
  13. package/core/test/acpsPrepare.test.ts +77 -0
  14. package/core/test/decryptBuilders.test.ts +51 -0
  15. package/core/test/encryptInputsBuilder.test.ts +4 -56
  16. package/dist/acps.d.cts +4 -358
  17. package/dist/acps.d.ts +4 -358
  18. package/dist/acps.js +2 -2
  19. package/dist/{chunk-WAA2U7CT.js → chunk-3L2IVPMI.js} +1 -1
  20. package/dist/{chunk-OC5TGQGG.js → chunk-J23FYAI2.js} +0 -1
  21. package/dist/{chunk-GKEJHZ52.js → chunk-VE7DKXSF.js} +132 -75
  22. package/dist/{chunk-3SD2UCRE.js → chunk-WJGTPW7K.js} +1 -1
  23. package/dist/{clientTypes-DEKYh0cw.d.ts → clientTypes-B-qOZCx0.d.ts} +55 -7
  24. package/dist/{clientTypes-C2b_qub5.d.cts → clientTypes-D2djRDoH.d.cts} +55 -7
  25. package/dist/core.cjs +128 -72
  26. package/dist/core.d.cts +3 -4
  27. package/dist/core.d.ts +3 -4
  28. package/dist/core.js +4 -4
  29. package/dist/node.cjs +128 -71
  30. package/dist/node.d.cts +2 -2
  31. package/dist/node.d.ts +2 -2
  32. package/dist/node.js +4 -4
  33. package/dist/{onchain-utils-CgOslubH.d.ts → onchain-utils-Ns56cBm0.d.cts} +356 -2
  34. package/dist/{onchain-utils-CgOslubH.d.cts → onchain-utils-Ns56cBm0.d.ts} +356 -2
  35. package/dist/web.cjs +128 -71
  36. package/dist/web.d.cts +2 -2
  37. package/dist/web.d.ts +2 -2
  38. package/dist/web.js +4 -4
  39. package/dist/zkProve.worker.js +2 -2
  40. package/package.json +1 -1
  41. package/core/test/zkPoKMetadata.test.ts +0 -27
@@ -1,7 +1,7 @@
1
- import { WalletClient, PublicClient, Hex } from 'viem';
1
+ import { WalletClient, PublicClient, Hex, ContractFunctionParameters } from 'viem';
2
2
  import { C as CofheChain } from './types-C07FK-cL.cjs';
3
3
  import { z } from 'zod';
4
- import { A as ACP, k as EIP712Domain, C as CreateSelfACPOptions, J as SelfACP, g as CreateSharingACPOptions, K as SharingACP, I as ImportSharedACPOptions, R as RecipientACP, P as ACPHashFields, f as SerializedACP, O as ACPAccessStatus, S as ShareLabel, j as IncomingShare, p as AclServedAddresses, L as LabelledShare, w as ShareLabelVerifyMode, x as ShareLabelCheck, l as ACPUtils } from './onchain-utils-CgOslubH.cjs';
4
+ import { A as ACP, k as EIP712Domain, C as CreateSelfACPOptions, $ as SelfACP, g as CreateSharingACPOptions, a0 as SharingACP, I as ImportSharedACPOptions, a1 as RecipientACP, a5 as ACPHashFields, f as SerializedACP, t as ACP_REVOKER_ABI, a4 as ACPAccessStatus, S as ShareLabel, v as ACP_SHARE_REGISTRY_ABI, j as IncomingShare, p as AclServedAddresses, L as LabelledShare, Q as ShareLabelVerifyMode, R as ShareLabelCheck, l as ACPUtils } from './onchain-utils-Ns56cBm0.cjs';
5
5
  import { StoreApi } from 'zustand/vanilla';
6
6
 
7
7
  type TfheInitializer = () => Promise<boolean>;
@@ -465,6 +465,7 @@ declare class DecryptForViewBuilder<U extends FheTypes> extends BaseBuilder {
465
465
  private acp?;
466
466
  private pollCallback?;
467
467
  private retry404TimeoutMs;
468
+ private timeoutMs?;
468
469
  constructor(params: DecryptForViewBuilderParams<U>);
469
470
  /**
470
471
  * @param chainId - Chain to decrypt values from. Used to fetch the threshold network URL and use the correct acp.
@@ -500,6 +501,12 @@ declare class DecryptForViewBuilder<U extends FheTypes> extends BaseBuilder {
500
501
  getAccount(): string | undefined;
501
502
  onPoll(callback: DecryptPollCallbackFunction): DecryptForViewBuilder<U>;
502
503
  set404RetryTimeout(timeoutMs: number): DecryptForViewBuilder<U>;
504
+ /**
505
+ * The whole budget of this decrypt in milliseconds, submit retries and status polling together
506
+ * (5 minutes by default). Past it, `execute()` rejects with `SealOutputFailed`; a request still
507
+ * processing on the threshold network is not cancelled.
508
+ */
509
+ setTimeout(timeoutMs: number): DecryptForViewBuilder<U>;
503
510
  /**
504
511
  * Select "use acp" mode (optional).
505
512
  *
@@ -603,6 +610,7 @@ declare class DecryptForTxBuilder extends BaseBuilder {
603
610
  private acpSelection;
604
611
  private pollCallback?;
605
612
  private retry404TimeoutMs;
613
+ private timeoutMs?;
606
614
  constructor(params: DecryptForTxBuilderParams);
607
615
  /**
608
616
  * @param chainId - Chain to decrypt values from. Used to fetch the threshold network URL and use the correct acp.
@@ -642,6 +650,13 @@ declare class DecryptForTxBuilder extends BaseBuilder {
642
650
  onPoll(this: DecryptForTxBuilderSelected, callback: DecryptPollCallbackFunction): DecryptForTxBuilderSelected;
643
651
  set404RetryTimeout(this: DecryptForTxBuilderUnset, timeoutMs: number): DecryptForTxBuilderUnset;
644
652
  set404RetryTimeout(this: DecryptForTxBuilderSelected, timeoutMs: number): DecryptForTxBuilderSelected;
653
+ /**
654
+ * The whole budget of this decrypt in milliseconds, submit retries and status polling together
655
+ * (5 minutes by default). Past it, `execute()` rejects with `DecryptFailed`; a request still
656
+ * processing on the threshold network is not cancelled.
657
+ */
658
+ setTimeout(this: DecryptForTxBuilderUnset, timeoutMs: number): DecryptForTxBuilderUnset;
659
+ setTimeout(this: DecryptForTxBuilderSelected, timeoutMs: number): DecryptForTxBuilderSelected;
645
660
  /**
646
661
  * Select "use acp" mode.
647
662
  *
@@ -896,11 +911,8 @@ declare class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuil
896
911
  setConsumingContract(address: string): EncryptInputsBuilder<T>;
897
912
  getConsumingContract(): string | undefined;
898
913
  /**
899
- * Asserts that this.consumingContract is populated and is an address.
900
- * Runs before TFHE init, key fetching and proving, so a bad address costs
901
- * nothing: the contract is bound into the proof, and a proof built for a
902
- * non-address could only fail at the verifier, after the expensive step.
903
- * @throws {CofheError} If consumingContract is not set or is not an address
914
+ * Asserts that this.consumingContract is populated
915
+ * @throws {CofheError} If consumingContract is not set
904
916
  */
905
917
  private assertConsumingContract;
906
918
  /**
@@ -1034,6 +1046,21 @@ type ImportSharedOptions = ImportActivationOptions & {
1034
1046
  */
1035
1047
  name?: string;
1036
1048
  };
1049
+ /**
1050
+ * Revoke a single acp on-chain via its revoker contract.
1051
+ * Only the acp's issuer can revoke it (enforced by the revoker: revocations
1052
+ * are keyed by msg.sender). The acp stays in local storage — on-chain
1053
+ * validation will reject it from the next block onwards.
1054
+ *
1055
+ * @returns the revocation transaction hash
1056
+ */
1057
+ /**
1058
+ * A registry or revoker write built but not sent: what a simulation or `writeContract` takes,
1059
+ * minus the sender. For a caller that sends through its own path (simulate first, record the
1060
+ * transaction) instead of the plain `writeContract` the senders below do.
1061
+ */
1062
+ type ShareRegistryWrite<functionName extends 'share' | 'removeShare'> = ContractFunctionParameters<typeof ACP_SHARE_REGISTRY_ABI, 'nonpayable', functionName>;
1063
+ type RevokerWrite = ContractFunctionParameters<typeof ACP_REVOKER_ABI, 'nonpayable', 'revokeSingle'>;
1037
1064
  /**
1038
1065
  * What `shareOnChain` posts with a share: the labels of its handles (one per handle, in order;
1039
1066
  * encoded with `encodeShareMetadata`), or an already encoded metadata blob. Written once, with the
@@ -1194,6 +1221,7 @@ declare const acps: {
1194
1221
  selectActiveACP: (chainId: number, account: string, hash: string) => void;
1195
1222
  removeActiveACP: (chainId: number, account: string) => Promise<void>;
1196
1223
  revokeACP: (acp: ACP, walletClient: WalletClient) => Promise<Hex>;
1224
+ prepareRevokeACP: (acp: ACP) => RevokerWrite;
1197
1225
  revokeAllACPs: (walletClient: WalletClient, publicClient: PublicClient, revokerContract?: Hex) => Promise<Hex>;
1198
1226
  isACPRevoked: (acp: ACP, publicClient: PublicClient) => Promise<boolean>;
1199
1227
  checkAccess: (acp: ACP, publicClient: PublicClient, handle?: bigint | Hex) => Promise<ACPAccessStatus>;
@@ -1201,12 +1229,17 @@ declare const acps: {
1201
1229
  txHash: Hex;
1202
1230
  shareId: Hex;
1203
1231
  }>;
1232
+ prepareShareOnChain: (acp: ACP, registry: Hex, options?: ShareOnChainOptions) => {
1233
+ write: ShareRegistryWrite<"share">;
1234
+ shareId: Hex;
1235
+ };
1204
1236
  getIncomingShares: (publicClient: PublicClient, registry: Hex, recipient: Hex, { appKey }?: {
1205
1237
  appKey?: Hex;
1206
1238
  }) => Promise<IncomingShare[]>;
1207
1239
  getShareFromChain: (publicClient: PublicClient, registry: Hex, shareId: Hex) => Promise<IncomingShare | null>;
1208
1240
  importFromChain: (share: IncomingShare, publicClient: PublicClient, walletClient: WalletClient, importOptions?: ImportSharedOptions) => Promise<RecipientACP>;
1209
1241
  removeShareOnChain: (shareId: Hex, walletClient: WalletClient, registry: Hex) => Promise<Hex>;
1242
+ prepareRemoveShare: (shareId: Hex, registry: Hex) => ShareRegistryWrite<"removeShare">;
1210
1243
  computeShareId: (acp: ACP) => Hex;
1211
1244
  applyACPDefaultsFromChain: <T extends {
1212
1245
  revokerData?: number;
@@ -1289,6 +1322,11 @@ type CofheClientACPs = {
1289
1322
  removeACP: (hash: string, chainId?: number, account?: string) => void;
1290
1323
  removeActiveACP: (chainId?: number, account?: string) => void;
1291
1324
  revokeACP: (acp: ACP) => Promise<`0x${string}`>;
1325
+ /**
1326
+ * The revoker write `revokeACP` sends, built but not sent — for an app that sends through its own
1327
+ * path (a simulation first, a transaction store). Issuer only; throws for an acp without a revoker.
1328
+ */
1329
+ prepareRevokeACP: (acp: ACP) => RevokerWrite;
1292
1330
  revokeAllACPs: (revokerContract?: `0x${string}`) => Promise<`0x${string}`>;
1293
1331
  isACPRevoked: (acp: ACP) => Promise<boolean>;
1294
1332
  /**
@@ -1306,6 +1344,16 @@ type CofheClientACPs = {
1306
1344
  txHash: `0x${string}`;
1307
1345
  shareId: `0x${string}`;
1308
1346
  }>;
1347
+ /**
1348
+ * The registry write `shareOnChain` sends and the share id it gets, built but not sent — for an
1349
+ * app that sends through its own path (a simulation first, a transaction store). Issuer only.
1350
+ */
1351
+ prepareShareOnChain: (acp: ACP, options?: ShareOnChainOptions) => Promise<{
1352
+ write: ShareRegistryWrite<'share'>;
1353
+ shareId: `0x${string}`;
1354
+ }>;
1355
+ /** The registry write `dismissShare` / `cancelShare` sends, built but not sent. */
1356
+ prepareRemoveShare: (shareId: `0x${string}`) => Promise<ShareRegistryWrite<'removeShare'>>;
1309
1357
  /** Importable shares addressed to the connected account (unexpired, not revoked), with their metadata. */
1310
1358
  getIncomingShares: () => Promise<IncomingShare[]>;
1311
1359
  /** One share by id, as posted; null when unknown or removed. */
package/dist/core.cjs CHANGED
@@ -60,7 +60,6 @@ var CofheErrorCode = /* @__PURE__ */ ((CofheErrorCode2) => {
60
60
  CofheErrorCode2["AccountUninitialized"] = "ACCOUNT_UNINITIALIZED";
61
61
  CofheErrorCode2["ChainIdUninitialized"] = "CHAIN_ID_UNINITIALIZED";
62
62
  CofheErrorCode2["ConsumingContractUninitialized"] = "CONSUMING_CONTRACT_UNINITIALIZED";
63
- CofheErrorCode2["ConsumingContractInvalid"] = "CONSUMING_CONTRACT_INVALID";
64
63
  CofheErrorCode2["SealOutputFailed"] = "SEAL_OUTPUT_FAILED";
65
64
  CofheErrorCode2["SealOutputReturnedNull"] = "SEAL_OUTPUT_RETURNED_NULL";
66
65
  CofheErrorCode2["InvalidUtype"] = "INVALID_UTYPE";
@@ -2130,22 +2129,19 @@ var zkProve = async (builder, crs, metadata) => {
2130
2129
  }, 0);
2131
2130
  });
2132
2131
  };
2133
- var constructZkPoKMetadata = (accountAddr, securityZone, chainId, consumingContract) => {
2132
+ var constructZkPoKMetadata = (accountAddr, securityZone, chainId) => {
2134
2133
  const accountAddrNoPrefix = accountAddr.startsWith("0x") ? accountAddr.slice(2) : accountAddr;
2135
2134
  const accountBytes = hexToBytes(accountAddrNoPrefix);
2136
- const contractNoPrefix = consumingContract.startsWith("0x") ? consumingContract.slice(2) : consumingContract;
2137
- const contractBytes = hexToBytes(contractNoPrefix);
2138
2135
  const chainIdBytes = new Uint8Array(32);
2139
2136
  let value = chainId;
2140
2137
  for (let i = 31; i >= 0 && value > 0; i--) {
2141
2138
  chainIdBytes[i] = value & 255;
2142
2139
  value = value >>> 8;
2143
2140
  }
2144
- const metadata = new Uint8Array(1 + accountBytes.length + 32 + contractBytes.length);
2141
+ const metadata = new Uint8Array(1 + accountBytes.length + 32);
2145
2142
  metadata[0] = securityZone;
2146
2143
  metadata.set(accountBytes, 1);
2147
2144
  metadata.set(chainIdBytes, 1 + accountBytes.length);
2148
- metadata.set(contractBytes, 1 + accountBytes.length + 32);
2149
2145
  return metadata;
2150
2146
  };
2151
2147
  var zkVerifyBatch = async (verifierUrl, serializedBytes, address, securityZone, chainId, consumingContract) => {
@@ -3061,33 +3057,20 @@ var EncryptInputsBuilder = class extends BaseBuilder {
3061
3057
  return this.consumingContract;
3062
3058
  }
3063
3059
  /**
3064
- * Asserts that this.consumingContract is populated and is an address.
3065
- * Runs before TFHE init, key fetching and proving, so a bad address costs
3066
- * nothing: the contract is bound into the proof, and a proof built for a
3067
- * non-address could only fail at the verifier, after the expensive step.
3068
- * @throws {CofheError} If consumingContract is not set or is not an address
3060
+ * Asserts that this.consumingContract is populated
3061
+ * @throws {CofheError} If consumingContract is not set
3069
3062
  */
3070
3063
  assertConsumingContract() {
3071
- if (!this.consumingContract) {
3072
- throw new CofheError({
3073
- code: "CONSUMING_CONTRACT_UNINITIALIZED" /* ConsumingContractUninitialized */,
3074
- message: "Consuming contract is not set",
3075
- hint: "Use setConsumingContract(...) to set the contract that will consume the encrypted inputs.",
3076
- context: {
3077
- consumingContract: this.consumingContract
3078
- }
3079
- });
3080
- }
3081
- if (!viem.isAddress(this.consumingContract, { strict: false })) {
3082
- throw new CofheError({
3083
- code: "CONSUMING_CONTRACT_INVALID" /* ConsumingContractInvalid */,
3084
- message: "Consuming contract is not an address",
3085
- hint: "setConsumingContract(...) takes the 20-byte address of the contract that will consume the encrypted inputs.",
3086
- context: {
3087
- consumingContract: this.consumingContract
3088
- }
3089
- });
3090
- }
3064
+ if (this.consumingContract)
3065
+ return;
3066
+ throw new CofheError({
3067
+ code: "CONSUMING_CONTRACT_UNINITIALIZED" /* ConsumingContractUninitialized */,
3068
+ message: "Consuming contract is not set",
3069
+ hint: "Use setConsumingContract(...) to set the contract that will consume the encrypted inputs.",
3070
+ context: {
3071
+ consumingContract: this.consumingContract
3072
+ }
3073
+ });
3091
3074
  }
3092
3075
  setUseWorker(useWorker) {
3093
3076
  this.useWorker = useWorker;
@@ -3303,7 +3286,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
3303
3286
  zkBuilder = zkPack(this.inputItems, zkBuilder);
3304
3287
  this.fireStepEnd("pack" /* Pack */);
3305
3288
  this.fireStepStart("prove" /* Prove */);
3306
- const metadata = constructZkPoKMetadata(this.account, this.securityZone, this.chainId, this.consumingContract);
3289
+ const metadata = constructZkPoKMetadata(this.account, this.securityZone, this.chainId);
3307
3290
  let proof = null;
3308
3291
  let usedWorker = false;
3309
3292
  let workerFailedError;
@@ -3481,23 +3464,25 @@ var getBlockRevokerData = async (publicClient) => {
3481
3464
  }
3482
3465
  return revokerData;
3483
3466
  };
3484
- var revokeACP = async (acp, walletClient) => {
3467
+ var prepareRevokeACP = (acp) => {
3485
3468
  if (acp.revokerContract === viem.zeroAddress || acp.revokerData === 0) {
3486
3469
  throw new Error("ACP is not revocable: it has no revoker (revokerContract/revokerData unset)");
3487
3470
  }
3471
+ return {
3472
+ address: acp.revokerContract,
3473
+ abi: ACP_REVOKER_ABI,
3474
+ functionName: "revokeSingle",
3475
+ args: [BigInt(acp.revokerData)]
3476
+ };
3477
+ };
3478
+ var revokeACP = async (acp, walletClient) => {
3479
+ const write = prepareRevokeACP(acp);
3488
3480
  if (walletClient.account == null)
3489
3481
  throw new Error("Missing walletClient account");
3490
3482
  if (walletClient.account.address.toLowerCase() !== acp.issuer.toLowerCase()) {
3491
3483
  throw new Error("Only the acp issuer can revoke it");
3492
3484
  }
3493
- return walletClient.writeContract({
3494
- address: acp.revokerContract,
3495
- abi: ACP_REVOKER_ABI,
3496
- functionName: "revokeSingle",
3497
- args: [BigInt(acp.revokerData)],
3498
- account: walletClient.account,
3499
- chain: walletClient.chain
3500
- });
3485
+ return walletClient.writeContract({ ...write, account: walletClient.account, chain: walletClient.chain });
3501
3486
  };
3502
3487
  var revokeAllACPs = async (walletClient, publicClient, revokerContract) => {
3503
3488
  if (walletClient.account == null)
@@ -3548,28 +3533,36 @@ var metadataOf = (acp, { labels, metadata, appKey }) => {
3548
3533
  }
3549
3534
  return encodeShareMetadata(labels, { issuer: acp.issuer, appKey });
3550
3535
  };
3551
- var shareOnChain = async (acp, walletClient, registry, options = {}) => {
3536
+ var prepareShareOnChain = (acp, registry, options = {}) => {
3552
3537
  if (acp.type !== "sharing") {
3553
3538
  throw new Error(`Cannot share a '${acp.type}' ACP on-chain \u2014 only 'sharing' ACPs are shareable.`);
3554
3539
  }
3555
3540
  if (acp.issuerSignature === "0x") {
3556
3541
  throw new Error("Cannot share an unsigned sharing ACP \u2014 sign it first.");
3557
3542
  }
3543
+ return {
3544
+ write: {
3545
+ address: registry,
3546
+ abi: ACP_SHARE_REGISTRY_ABI,
3547
+ functionName: "share",
3548
+ args: [toChainShare(acp), metadataOf(acp, options)]
3549
+ },
3550
+ shareId: computeShareId(acp)
3551
+ };
3552
+ };
3553
+ var shareOnChain = async (acp, walletClient, registry, options = {}) => {
3554
+ const { write, shareId } = prepareShareOnChain(acp, registry, options);
3558
3555
  if (walletClient.account == null)
3559
3556
  throw new Error("Missing walletClient account");
3560
3557
  if (walletClient.account.address.toLowerCase() !== acp.issuer.toLowerCase()) {
3561
3558
  throw new Error("Only the ACP issuer can share it on-chain");
3562
3559
  }
3563
- const metadata = metadataOf(acp, options);
3564
3560
  const txHash = await walletClient.writeContract({
3565
- address: registry,
3566
- abi: ACP_SHARE_REGISTRY_ABI,
3567
- functionName: "share",
3568
- args: [toChainShare(acp), metadata],
3561
+ ...write,
3569
3562
  account: walletClient.account,
3570
3563
  chain: walletClient.chain ?? null
3571
3564
  });
3572
- return { txHash, shareId: computeShareId(acp) };
3565
+ return { txHash, shareId };
3573
3566
  };
3574
3567
  var toIncomingShare = ({ shareId, share: s, metadata }) => ({
3575
3568
  shareId,
@@ -3604,14 +3597,17 @@ var importFromChain = async (share, publicClient, walletClient, importOptions =
3604
3597
  const { shareId: _shareId, appKey: _appKey, ...options } = share;
3605
3598
  return importShared({ ...options, type: "sharing" }, publicClient, walletClient, importOptions);
3606
3599
  };
3600
+ var prepareRemoveShare = (shareId, registry) => ({
3601
+ address: registry,
3602
+ abi: ACP_SHARE_REGISTRY_ABI,
3603
+ functionName: "removeShare",
3604
+ args: [shareId]
3605
+ });
3607
3606
  var removeShareOnChain = async (shareId, walletClient, registry) => {
3608
3607
  if (walletClient.account == null)
3609
3608
  throw new Error("Missing walletClient account");
3610
3609
  return walletClient.writeContract({
3611
- address: registry,
3612
- abi: ACP_SHARE_REGISTRY_ABI,
3613
- functionName: "removeShare",
3614
- args: [shareId],
3610
+ ...prepareRemoveShare(shareId, registry),
3615
3611
  account: walletClient.account,
3616
3612
  chain: walletClient.chain ?? null
3617
3613
  });
@@ -3638,14 +3634,17 @@ var acps = {
3638
3634
  selectActiveACP,
3639
3635
  removeActiveACP,
3640
3636
  revokeACP,
3637
+ prepareRevokeACP,
3641
3638
  revokeAllACPs,
3642
3639
  isACPRevoked,
3643
3640
  checkAccess,
3644
3641
  shareOnChain,
3642
+ prepareShareOnChain,
3645
3643
  getIncomingShares,
3646
3644
  getShareFromChain,
3647
3645
  importFromChain,
3648
3646
  removeShareOnChain,
3647
+ prepareRemoveShare,
3649
3648
  computeShareId,
3650
3649
  applyACPDefaultsFromChain,
3651
3650
  getAclServedAddresses,
@@ -3985,6 +3984,16 @@ function mapApiErrorCodeToCofheErrorCode(apiErrorCode, fallback) {
3985
3984
 
3986
3985
  // core/decrypt/submitRetry.ts
3987
3986
  var DEFAULT_404_RETRY_TIMEOUT_MS = 1e4;
3987
+ var DEFAULT_DECRYPT_TIMEOUT_MS = 5 * 60 * 1e3;
3988
+ function assertDecryptTimeoutMs(timeoutMs, operationLabel) {
3989
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
3990
+ throw new CofheError({
3991
+ code: "INTERNAL_ERROR" /* InternalError */,
3992
+ message: `${operationLabel}: setTimeout(timeoutMs) expects a finite number greater than 0.`,
3993
+ context: { timeoutMs }
3994
+ });
3995
+ }
3996
+ }
3988
3997
  function normalize404RetryTimeoutMs(params) {
3989
3998
  const { timeoutMs, operationLabel, errorCode } = params;
3990
3999
  if (timeoutMs === void 0)
@@ -4123,7 +4132,6 @@ function parseDecryptedBytesToBigInt(decrypted) {
4123
4132
  // core/decrypt/tnSealOutputV2.ts
4124
4133
  var POLL_INTERVAL_MS = 1e3;
4125
4134
  var POLL_MAX_INTERVAL_MS = 1e4;
4126
- var SEAL_OUTPUT_TIMEOUT_MS = 5 * 60 * 1e3;
4127
4135
  var SUBMIT_RETRY_INTERVAL_MS = 1e3;
4128
4136
  function numberArrayToUint8Array(arr) {
4129
4137
  return new Uint8Array(arr);
@@ -4181,7 +4189,7 @@ function parseCompletedSealOutputResponse(params) {
4181
4189
  }
4182
4190
  return convertSealedData(sealed);
4183
4191
  }
4184
- async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, onPoll) {
4192
+ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, timeoutMs, onPoll) {
4185
4193
  const body = {
4186
4194
  ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
4187
4195
  host_chain_id: chainId,
@@ -4284,7 +4292,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp
4284
4292
  status: responseClassification.status,
4285
4293
  elapsedMs,
4286
4294
  retry404TimeoutMs,
4287
- overallTimeoutMs: SEAL_OUTPUT_TIMEOUT_MS,
4295
+ overallTimeoutMs: timeoutMs,
4288
4296
  thresholdNetworkUrl,
4289
4297
  body,
4290
4298
  attemptIndex,
@@ -4296,13 +4304,13 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp
4296
4304
  attemptIndex,
4297
4305
  elapsedMs,
4298
4306
  intervalMs: SUBMIT_RETRY_INTERVAL_MS,
4299
- timeoutMs: SEAL_OUTPUT_TIMEOUT_MS
4307
+ timeoutMs
4300
4308
  });
4301
4309
  await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS));
4302
4310
  attemptIndex += 1;
4303
4311
  }
4304
4312
  }
4305
- async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStartTime, onPoll) {
4313
+ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStartTime, timeoutMs, onPoll) {
4306
4314
  let attemptIndex = 0;
4307
4315
  while (true) {
4308
4316
  const elapsedMs = Date.now() - overallStartTime;
@@ -4316,17 +4324,17 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
4316
4324
  attemptIndex,
4317
4325
  elapsedMs,
4318
4326
  intervalMs,
4319
- timeoutMs: SEAL_OUTPUT_TIMEOUT_MS
4327
+ timeoutMs
4320
4328
  });
4321
- if (elapsedMs > SEAL_OUTPUT_TIMEOUT_MS) {
4329
+ if (elapsedMs > timeoutMs) {
4322
4330
  throw new CofheError({
4323
4331
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
4324
- message: `sealOutput polling timed out after ${SEAL_OUTPUT_TIMEOUT_MS}ms`,
4332
+ message: `sealOutput polling timed out after ${timeoutMs}ms`,
4325
4333
  hint: "The request may still be processing. Try again later.",
4326
4334
  context: {
4327
4335
  thresholdNetworkUrl,
4328
4336
  requestId,
4329
- timeoutMs: SEAL_OUTPUT_TIMEOUT_MS
4337
+ timeoutMs
4330
4338
  }
4331
4339
  });
4332
4340
  }
@@ -4414,6 +4422,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
4414
4422
  }
4415
4423
  async function tnSealOutputV2(params) {
4416
4424
  const { thresholdNetworkUrl, ctHash, chainId, acp, retry404TimeoutMs, onPoll } = params;
4425
+ const timeoutMs = params.timeoutMs ?? DEFAULT_DECRYPT_TIMEOUT_MS;
4417
4426
  const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
4418
4427
  timeoutMs: retry404TimeoutMs,
4419
4428
  operationLabel: "sealOutput",
@@ -4427,12 +4436,13 @@ async function tnSealOutputV2(params) {
4427
4436
  acp,
4428
4437
  overallStartTime,
4429
4438
  normalized404RetryTimeoutMs,
4439
+ timeoutMs,
4430
4440
  onPoll
4431
4441
  );
4432
4442
  if (submitResult.kind === "completed") {
4433
4443
  return submitResult.sealed;
4434
4444
  }
4435
- return await pollSealOutputStatus(thresholdNetworkUrl, submitResult.requestId, overallStartTime, onPoll);
4445
+ return await pollSealOutputStatus(thresholdNetworkUrl, submitResult.requestId, overallStartTime, timeoutMs, onPoll);
4436
4446
  }
4437
4447
 
4438
4448
  // core/decrypt/decryptForViewBuilder.ts
@@ -4444,6 +4454,7 @@ var DecryptForViewBuilder = class extends BaseBuilder {
4444
4454
  acp;
4445
4455
  pollCallback;
4446
4456
  retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS2;
4457
+ timeoutMs;
4447
4458
  constructor(params) {
4448
4459
  super({
4449
4460
  config: params.config,
@@ -4517,6 +4528,16 @@ var DecryptForViewBuilder = class extends BaseBuilder {
4517
4528
  this.retry404TimeoutMs = timeoutMs;
4518
4529
  return this;
4519
4530
  }
4531
+ /**
4532
+ * The whole budget of this decrypt in milliseconds, submit retries and status polling together
4533
+ * (5 minutes by default). Past it, `execute()` rejects with `SealOutputFailed`; a request still
4534
+ * processing on the threshold network is not cancelled.
4535
+ */
4536
+ setTimeout(timeoutMs) {
4537
+ assertDecryptTimeoutMs(timeoutMs, "decryptForView");
4538
+ this.timeoutMs = timeoutMs;
4539
+ return this;
4540
+ }
4520
4541
  withACP(acpOrACPHash) {
4521
4542
  if (typeof acpOrACPHash === "string") {
4522
4543
  this.acpHash = acpOrACPHash;
@@ -4646,6 +4667,7 @@ var DecryptForViewBuilder = class extends BaseBuilder {
4646
4667
  acp: wireAcp,
4647
4668
  thresholdNetworkUrl,
4648
4669
  retry404TimeoutMs: this.retry404TimeoutMs,
4670
+ timeoutMs: this.timeoutMs,
4649
4671
  onPoll: this.pollCallback
4650
4672
  });
4651
4673
  return ACPUtils.unseal(acp, sealed);
@@ -4748,7 +4770,6 @@ async function cofheMocksDecryptForTx(ctHash, utype, acp, publicClient) {
4748
4770
  // core/decrypt/tnDecryptV2.ts
4749
4771
  var POLL_INTERVAL_MS2 = 1e3;
4750
4772
  var POLL_MAX_INTERVAL_MS2 = 1e4;
4751
- var DECRYPT_TIMEOUT_MS = 5 * 60 * 1e3;
4752
4773
  var SUBMIT_RETRY_INTERVAL_MS2 = 1e3;
4753
4774
  function assertDecryptSubmitResponseV2(value) {
4754
4775
  if (value == null || typeof value !== "object") {
@@ -4865,7 +4886,7 @@ function assertDecryptStatusResponseV2(value) {
4865
4886
  }
4866
4887
  return value;
4867
4888
  }
4868
- async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, onPoll) {
4889
+ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, timeoutMs, onPoll) {
4869
4890
  const body = {
4870
4891
  ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
4871
4892
  host_chain_id: chainId
@@ -4972,7 +4993,7 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp,
4972
4993
  status: responseClassification.status,
4973
4994
  elapsedMs,
4974
4995
  retry404TimeoutMs,
4975
- overallTimeoutMs: DECRYPT_TIMEOUT_MS,
4996
+ overallTimeoutMs: timeoutMs,
4976
4997
  thresholdNetworkUrl,
4977
4998
  body,
4978
4999
  attemptIndex,
@@ -4984,13 +5005,13 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp,
4984
5005
  attemptIndex,
4985
5006
  elapsedMs,
4986
5007
  intervalMs: SUBMIT_RETRY_INTERVAL_MS2,
4987
- timeoutMs: DECRYPT_TIMEOUT_MS
5008
+ timeoutMs
4988
5009
  });
4989
5010
  await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS2));
4990
5011
  attemptIndex += 1;
4991
5012
  }
4992
5013
  }
4993
- async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartTime, onPoll) {
5014
+ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartTime, timeoutMs, onPoll) {
4994
5015
  let attemptIndex = 0;
4995
5016
  while (true) {
4996
5017
  const elapsedMs = Date.now() - overallStartTime;
@@ -5004,17 +5025,17 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
5004
5025
  attemptIndex,
5005
5026
  elapsedMs,
5006
5027
  intervalMs,
5007
- timeoutMs: DECRYPT_TIMEOUT_MS
5028
+ timeoutMs
5008
5029
  });
5009
- if (elapsedMs > DECRYPT_TIMEOUT_MS) {
5030
+ if (elapsedMs > timeoutMs) {
5010
5031
  throw new CofheError({
5011
5032
  code: "DECRYPT_FAILED" /* DecryptFailed */,
5012
- message: `decrypt polling timed out after ${DECRYPT_TIMEOUT_MS}ms`,
5033
+ message: `decrypt polling timed out after ${timeoutMs}ms`,
5013
5034
  hint: "The request may still be processing. Try again later.",
5014
5035
  context: {
5015
5036
  thresholdNetworkUrl,
5016
5037
  requestId,
5017
- timeoutMs: DECRYPT_TIMEOUT_MS
5038
+ timeoutMs
5018
5039
  }
5019
5040
  });
5020
5041
  }
@@ -5103,6 +5124,7 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
5103
5124
  }
5104
5125
  async function tnDecryptV2(params) {
5105
5126
  const { thresholdNetworkUrl, ctHash, chainId, acp, retry404TimeoutMs, onPoll } = params;
5127
+ const timeoutMs = params.timeoutMs ?? DEFAULT_DECRYPT_TIMEOUT_MS;
5106
5128
  const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
5107
5129
  timeoutMs: retry404TimeoutMs,
5108
5130
  operationLabel: "decrypt",
@@ -5116,12 +5138,13 @@ async function tnDecryptV2(params) {
5116
5138
  acp,
5117
5139
  overallStartTime,
5118
5140
  normalized404RetryTimeoutMs,
5141
+ timeoutMs,
5119
5142
  onPoll
5120
5143
  );
5121
5144
  if (submitResult.kind === "completed") {
5122
5145
  return submitResult;
5123
5146
  }
5124
- return await pollDecryptStatusV2(thresholdNetworkUrl, submitResult.requestId, overallStartTime, onPoll);
5147
+ return await pollDecryptStatusV2(thresholdNetworkUrl, submitResult.requestId, overallStartTime, timeoutMs, onPoll);
5125
5148
  }
5126
5149
 
5127
5150
  // core/decrypt/decryptForTxBuilder.ts
@@ -5133,6 +5156,7 @@ var DecryptForTxBuilder = class extends BaseBuilder {
5133
5156
  acpSelection = "unset";
5134
5157
  pollCallback;
5135
5158
  retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS3;
5159
+ timeoutMs;
5136
5160
  constructor(params) {
5137
5161
  super({
5138
5162
  config: params.config,
@@ -5175,6 +5199,11 @@ var DecryptForTxBuilder = class extends BaseBuilder {
5175
5199
  this.retry404TimeoutMs = timeoutMs;
5176
5200
  return this;
5177
5201
  }
5202
+ setTimeout(timeoutMs) {
5203
+ assertDecryptTimeoutMs(timeoutMs, "decryptForTx");
5204
+ this.timeoutMs = timeoutMs;
5205
+ return this;
5206
+ }
5178
5207
  withACP(acpOrACPHash) {
5179
5208
  if (this.acpSelection === "with-acp") {
5180
5209
  throw new CofheError({
@@ -5308,6 +5337,7 @@ var DecryptForTxBuilder = class extends BaseBuilder {
5308
5337
  acp: wireAcp,
5309
5338
  thresholdNetworkUrl,
5310
5339
  retry404TimeoutMs: this.retry404TimeoutMs,
5340
+ timeoutMs: this.timeoutMs,
5311
5341
  onPoll: this.pollCallback
5312
5342
  });
5313
5343
  return {
@@ -5428,6 +5458,12 @@ function createCofheClientBase(opts) {
5428
5458
  });
5429
5459
  }
5430
5460
  };
5461
+ const _requireIssuer = (acp, what) => {
5462
+ const sender = connectStore.getState().walletClient?.account?.address;
5463
+ if (sender == null || sender.toLowerCase() !== acp.issuer.toLowerCase()) {
5464
+ throw new Error(`Only the acp issuer can ${what}`);
5465
+ }
5466
+ };
5431
5467
  async function connect(publicClient, walletClient) {
5432
5468
  const state = connectStore.getState();
5433
5469
  if (state.connected && state.publicClient === publicClient && state.walletClient === walletClient)
@@ -5595,6 +5631,11 @@ function createCofheClientBase(opts) {
5595
5631
  const { walletClient } = connectStore.getState();
5596
5632
  return acps.revokeACP(acp, walletClient);
5597
5633
  },
5634
+ prepareRevokeACP: (acp) => {
5635
+ _requireConnected();
5636
+ _requireIssuer(acp, "revoke it");
5637
+ return acps.prepareRevokeACP(acp);
5638
+ },
5598
5639
  revokeAllACPs: async (revokerContract) => {
5599
5640
  _requireConnected();
5600
5641
  const { publicClient, walletClient } = connectStore.getState();
@@ -5618,6 +5659,21 @@ function createCofheClientBase(opts) {
5618
5659
  const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
5619
5660
  return acps.shareOnChain(acp, walletClient, sharingRegistry, { ...withAppKey(), ...options });
5620
5661
  },
5662
+ prepareShareOnChain: async (acp, options) => {
5663
+ _requireConnected();
5664
+ _requireIssuer(acp, "share it on-chain");
5665
+ const { publicClient } = connectStore.getState();
5666
+ const chainId = await publicClient.getChainId();
5667
+ const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
5668
+ return acps.prepareShareOnChain(acp, sharingRegistry, { ...withAppKey(), ...options });
5669
+ },
5670
+ prepareRemoveShare: async (shareId) => {
5671
+ _requireConnected();
5672
+ const { publicClient } = connectStore.getState();
5673
+ const chainId = await publicClient.getChainId();
5674
+ const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
5675
+ return acps.prepareRemoveShare(shareId, sharingRegistry);
5676
+ },
5621
5677
  getIncomingShares: async () => {
5622
5678
  _requireConnected();
5623
5679
  const { publicClient, walletClient } = connectStore.getState();
package/dist/core.d.cts CHANGED
@@ -1,9 +1,9 @@
1
- import { a as CofheConfig, c as CofheClientParams, b as CofheClient, d as CofheClientConnectionState, F as FheTypes } from './clientTypes-C2b_qub5.cjs';
2
- export { A as AnyExternalHash, i as CofheClientACPs, C as CofheInputConfig, h as CofheInternalConfig, K as DecryptEndpoint, a4 as DecryptForTxBuilder, a5 as DecryptForTxResult, a3 as DecryptForViewBuilder, J as DecryptPollCallbackContext, G as DecryptPollCallbackFunction, a1 as EncryptInputsBuilder, a2 as EncryptInputsBuilderUnset, M as EncryptSetStateFn, W as EncryptStep, N as EncryptStepCallbackContext, S as Encryptable, p as EncryptableAddress, j as EncryptableBool, E as EncryptableItem, B as EncryptableToExternalHashMap, o as EncryptableUint128, l as EncryptableUint16, m as EncryptableUint32, n as EncryptableUint64, k as EncryptableUint8, q as EncryptedNumber, y as ExternalAddressHash, s as ExternalBoolHash, z as ExternalHashProof, D as ExternalItemHashes, x as ExternalUint128Hash, u as ExternalUint16Hash, v as ExternalUint32Hash, w as ExternalUint64Hash, t as ExternalUint8Hash, R as FheAllUTypes, Z as FheKeyDeserializer, r as FheTypeValue, Q as FheUintUTypes, H as HashPlusProofResult, I as IStorage, $ as KeysStorage, a0 as KeysStore, L as LiteralToPrimitive, P as Primitive, T as TfheInitializer, O as TfheThreadsSetting, U as UnsealedItem, a6 as ZkBuilderAndCrsGenerator, a7 as ZkProveWorkerFunction, a8 as ZkProveWorkerRequest, a9 as ZkProveWorkerResponse, f as assertNoRenamedConfigKeys, e as createCofheConfigBase, _ as createKeysStore, Y as fetchKeys, g as getCofheConfigItem, V as isEncryptableItem, X as isLastEncryptionStep, aa as zkProveWithWorker } from './clientTypes-C2b_qub5.cjs';
1
+ import { a as CofheConfig, c as CofheClientParams, b as CofheClient, d as CofheClientConnectionState, F as FheTypes } from './clientTypes-D2djRDoH.cjs';
2
+ export { A as AnyExternalHash, i as CofheClientACPs, C as CofheInputConfig, h as CofheInternalConfig, K as DecryptEndpoint, a4 as DecryptForTxBuilder, a5 as DecryptForTxResult, a3 as DecryptForViewBuilder, J as DecryptPollCallbackContext, G as DecryptPollCallbackFunction, a1 as EncryptInputsBuilder, a2 as EncryptInputsBuilderUnset, M as EncryptSetStateFn, W as EncryptStep, N as EncryptStepCallbackContext, S as Encryptable, p as EncryptableAddress, j as EncryptableBool, E as EncryptableItem, B as EncryptableToExternalHashMap, o as EncryptableUint128, l as EncryptableUint16, m as EncryptableUint32, n as EncryptableUint64, k as EncryptableUint8, q as EncryptedNumber, y as ExternalAddressHash, s as ExternalBoolHash, z as ExternalHashProof, D as ExternalItemHashes, x as ExternalUint128Hash, u as ExternalUint16Hash, v as ExternalUint32Hash, w as ExternalUint64Hash, t as ExternalUint8Hash, R as FheAllUTypes, Z as FheKeyDeserializer, r as FheTypeValue, Q as FheUintUTypes, H as HashPlusProofResult, I as IStorage, $ as KeysStorage, a0 as KeysStore, L as LiteralToPrimitive, P as Primitive, T as TfheInitializer, O as TfheThreadsSetting, U as UnsealedItem, a6 as ZkBuilderAndCrsGenerator, a7 as ZkProveWorkerFunction, a8 as ZkProveWorkerRequest, a9 as ZkProveWorkerResponse, f as assertNoRenamedConfigKeys, e as createCofheConfigBase, _ as createKeysStore, Y as fetchKeys, g as getCofheConfigItem, V as isEncryptableItem, X as isLastEncryptionStep, aa as zkProveWithWorker } from './clientTypes-D2djRDoH.cjs';
3
3
  import { PublicClient, Address, Hex } from 'viem';
4
4
  import './types-C07FK-cL.cjs';
5
5
  import 'zod';
6
- import './onchain-utils-CgOslubH.cjs';
6
+ import './onchain-utils-Ns56cBm0.cjs';
7
7
  import 'zustand/vanilla';
8
8
 
9
9
  declare const InitialConnectStore: CofheClientConnectionState;
@@ -55,7 +55,6 @@ declare enum CofheErrorCode {
55
55
  AccountUninitialized = "ACCOUNT_UNINITIALIZED",
56
56
  ChainIdUninitialized = "CHAIN_ID_UNINITIALIZED",
57
57
  ConsumingContractUninitialized = "CONSUMING_CONTRACT_UNINITIALIZED",
58
- ConsumingContractInvalid = "CONSUMING_CONTRACT_INVALID",
59
58
  SealOutputFailed = "SEAL_OUTPUT_FAILED",
60
59
  SealOutputReturnedNull = "SEAL_OUTPUT_RETURNED_NULL",
61
60
  InvalidUtype = "INVALID_UTYPE",