@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
package/dist/web.cjs CHANGED
@@ -1960,22 +1960,19 @@ var zkProve = async (builder, crs, metadata) => {
1960
1960
  }, 0);
1961
1961
  });
1962
1962
  };
1963
- var constructZkPoKMetadata = (accountAddr, securityZone, chainId, consumingContract) => {
1963
+ var constructZkPoKMetadata = (accountAddr, securityZone, chainId) => {
1964
1964
  const accountAddrNoPrefix = accountAddr.startsWith("0x") ? accountAddr.slice(2) : accountAddr;
1965
1965
  const accountBytes = hexToBytes(accountAddrNoPrefix);
1966
- const contractNoPrefix = consumingContract.startsWith("0x") ? consumingContract.slice(2) : consumingContract;
1967
- const contractBytes = hexToBytes(contractNoPrefix);
1968
1966
  const chainIdBytes = new Uint8Array(32);
1969
1967
  let value = chainId;
1970
1968
  for (let i = 31; i >= 0 && value > 0; i--) {
1971
1969
  chainIdBytes[i] = value & 255;
1972
1970
  value = value >>> 8;
1973
1971
  }
1974
- const metadata = new Uint8Array(1 + accountBytes.length + 32 + contractBytes.length);
1972
+ const metadata = new Uint8Array(1 + accountBytes.length + 32);
1975
1973
  metadata[0] = securityZone;
1976
1974
  metadata.set(accountBytes, 1);
1977
1975
  metadata.set(chainIdBytes, 1 + accountBytes.length);
1978
- metadata.set(contractBytes, 1 + accountBytes.length + 32);
1979
1976
  return metadata;
1980
1977
  };
1981
1978
  var zkVerifyBatch = async (verifierUrl, serializedBytes, address, securityZone, chainId, consumingContract) => {
@@ -2888,33 +2885,20 @@ var EncryptInputsBuilder = class extends BaseBuilder {
2888
2885
  return this.consumingContract;
2889
2886
  }
2890
2887
  /**
2891
- * Asserts that this.consumingContract is populated and is an address.
2892
- * Runs before TFHE init, key fetching and proving, so a bad address costs
2893
- * nothing: the contract is bound into the proof, and a proof built for a
2894
- * non-address could only fail at the verifier, after the expensive step.
2895
- * @throws {CofheError} If consumingContract is not set or is not an address
2888
+ * Asserts that this.consumingContract is populated
2889
+ * @throws {CofheError} If consumingContract is not set
2896
2890
  */
2897
2891
  assertConsumingContract() {
2898
- if (!this.consumingContract) {
2899
- throw new CofheError({
2900
- code: "CONSUMING_CONTRACT_UNINITIALIZED" /* ConsumingContractUninitialized */,
2901
- message: "Consuming contract is not set",
2902
- hint: "Use setConsumingContract(...) to set the contract that will consume the encrypted inputs.",
2903
- context: {
2904
- consumingContract: this.consumingContract
2905
- }
2906
- });
2907
- }
2908
- if (!viem.isAddress(this.consumingContract, { strict: false })) {
2909
- throw new CofheError({
2910
- code: "CONSUMING_CONTRACT_INVALID" /* ConsumingContractInvalid */,
2911
- message: "Consuming contract is not an address",
2912
- hint: "setConsumingContract(...) takes the 20-byte address of the contract that will consume the encrypted inputs.",
2913
- context: {
2914
- consumingContract: this.consumingContract
2915
- }
2916
- });
2917
- }
2892
+ if (this.consumingContract)
2893
+ return;
2894
+ throw new CofheError({
2895
+ code: "CONSUMING_CONTRACT_UNINITIALIZED" /* ConsumingContractUninitialized */,
2896
+ message: "Consuming contract is not set",
2897
+ hint: "Use setConsumingContract(...) to set the contract that will consume the encrypted inputs.",
2898
+ context: {
2899
+ consumingContract: this.consumingContract
2900
+ }
2901
+ });
2918
2902
  }
2919
2903
  setUseWorker(useWorker) {
2920
2904
  this.useWorker = useWorker;
@@ -3130,7 +3114,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
3130
3114
  zkBuilder = zkPack(this.inputItems, zkBuilder);
3131
3115
  this.fireStepEnd("pack" /* Pack */);
3132
3116
  this.fireStepStart("prove" /* Prove */);
3133
- const metadata = constructZkPoKMetadata(this.account, this.securityZone, this.chainId, this.consumingContract);
3117
+ const metadata = constructZkPoKMetadata(this.account, this.securityZone, this.chainId);
3134
3118
  let proof = null;
3135
3119
  let usedWorker = false;
3136
3120
  let workerFailedError;
@@ -3308,23 +3292,25 @@ var getBlockRevokerData = async (publicClient) => {
3308
3292
  }
3309
3293
  return revokerData;
3310
3294
  };
3311
- var revokeACP = async (acp, walletClient) => {
3295
+ var prepareRevokeACP = (acp) => {
3312
3296
  if (acp.revokerContract === viem.zeroAddress || acp.revokerData === 0) {
3313
3297
  throw new Error("ACP is not revocable: it has no revoker (revokerContract/revokerData unset)");
3314
3298
  }
3299
+ return {
3300
+ address: acp.revokerContract,
3301
+ abi: ACP_REVOKER_ABI,
3302
+ functionName: "revokeSingle",
3303
+ args: [BigInt(acp.revokerData)]
3304
+ };
3305
+ };
3306
+ var revokeACP = async (acp, walletClient) => {
3307
+ const write = prepareRevokeACP(acp);
3315
3308
  if (walletClient.account == null)
3316
3309
  throw new Error("Missing walletClient account");
3317
3310
  if (walletClient.account.address.toLowerCase() !== acp.issuer.toLowerCase()) {
3318
3311
  throw new Error("Only the acp issuer can revoke it");
3319
3312
  }
3320
- return walletClient.writeContract({
3321
- address: acp.revokerContract,
3322
- abi: ACP_REVOKER_ABI,
3323
- functionName: "revokeSingle",
3324
- args: [BigInt(acp.revokerData)],
3325
- account: walletClient.account,
3326
- chain: walletClient.chain
3327
- });
3313
+ return walletClient.writeContract({ ...write, account: walletClient.account, chain: walletClient.chain });
3328
3314
  };
3329
3315
  var revokeAllACPs = async (walletClient, publicClient, revokerContract) => {
3330
3316
  if (walletClient.account == null)
@@ -3375,28 +3361,36 @@ var metadataOf = (acp, { labels, metadata, appKey }) => {
3375
3361
  }
3376
3362
  return encodeShareMetadata(labels, { issuer: acp.issuer, appKey });
3377
3363
  };
3378
- var shareOnChain = async (acp, walletClient, registry, options = {}) => {
3364
+ var prepareShareOnChain = (acp, registry, options = {}) => {
3379
3365
  if (acp.type !== "sharing") {
3380
3366
  throw new Error(`Cannot share a '${acp.type}' ACP on-chain \u2014 only 'sharing' ACPs are shareable.`);
3381
3367
  }
3382
3368
  if (acp.issuerSignature === "0x") {
3383
3369
  throw new Error("Cannot share an unsigned sharing ACP \u2014 sign it first.");
3384
3370
  }
3371
+ return {
3372
+ write: {
3373
+ address: registry,
3374
+ abi: ACP_SHARE_REGISTRY_ABI,
3375
+ functionName: "share",
3376
+ args: [toChainShare(acp), metadataOf(acp, options)]
3377
+ },
3378
+ shareId: computeShareId(acp)
3379
+ };
3380
+ };
3381
+ var shareOnChain = async (acp, walletClient, registry, options = {}) => {
3382
+ const { write, shareId } = prepareShareOnChain(acp, registry, options);
3385
3383
  if (walletClient.account == null)
3386
3384
  throw new Error("Missing walletClient account");
3387
3385
  if (walletClient.account.address.toLowerCase() !== acp.issuer.toLowerCase()) {
3388
3386
  throw new Error("Only the ACP issuer can share it on-chain");
3389
3387
  }
3390
- const metadata = metadataOf(acp, options);
3391
3388
  const txHash = await walletClient.writeContract({
3392
- address: registry,
3393
- abi: ACP_SHARE_REGISTRY_ABI,
3394
- functionName: "share",
3395
- args: [toChainShare(acp), metadata],
3389
+ ...write,
3396
3390
  account: walletClient.account,
3397
3391
  chain: walletClient.chain ?? null
3398
3392
  });
3399
- return { txHash, shareId: computeShareId(acp) };
3393
+ return { txHash, shareId };
3400
3394
  };
3401
3395
  var toIncomingShare = ({ shareId, share: s, metadata }) => ({
3402
3396
  shareId,
@@ -3431,14 +3425,17 @@ var importFromChain = async (share, publicClient, walletClient, importOptions =
3431
3425
  const { shareId: _shareId, appKey: _appKey, ...options } = share;
3432
3426
  return importShared({ ...options, type: "sharing" }, publicClient, walletClient, importOptions);
3433
3427
  };
3428
+ var prepareRemoveShare = (shareId, registry) => ({
3429
+ address: registry,
3430
+ abi: ACP_SHARE_REGISTRY_ABI,
3431
+ functionName: "removeShare",
3432
+ args: [shareId]
3433
+ });
3434
3434
  var removeShareOnChain = async (shareId, walletClient, registry) => {
3435
3435
  if (walletClient.account == null)
3436
3436
  throw new Error("Missing walletClient account");
3437
3437
  return walletClient.writeContract({
3438
- address: registry,
3439
- abi: ACP_SHARE_REGISTRY_ABI,
3440
- functionName: "removeShare",
3441
- args: [shareId],
3438
+ ...prepareRemoveShare(shareId, registry),
3442
3439
  account: walletClient.account,
3443
3440
  chain: walletClient.chain ?? null
3444
3441
  });
@@ -3465,14 +3462,17 @@ var acps = {
3465
3462
  selectActiveACP,
3466
3463
  removeActiveACP,
3467
3464
  revokeACP,
3465
+ prepareRevokeACP,
3468
3466
  revokeAllACPs,
3469
3467
  isACPRevoked,
3470
3468
  checkAccess,
3471
3469
  shareOnChain,
3470
+ prepareShareOnChain,
3472
3471
  getIncomingShares,
3473
3472
  getShareFromChain,
3474
3473
  importFromChain,
3475
3474
  removeShareOnChain,
3475
+ prepareRemoveShare,
3476
3476
  computeShareId,
3477
3477
  applyACPDefaultsFromChain,
3478
3478
  getAclServedAddresses,
@@ -3805,6 +3805,16 @@ function mapApiErrorCodeToCofheErrorCode(apiErrorCode, fallback) {
3805
3805
 
3806
3806
  // core/decrypt/submitRetry.ts
3807
3807
  var DEFAULT_404_RETRY_TIMEOUT_MS = 1e4;
3808
+ var DEFAULT_DECRYPT_TIMEOUT_MS = 5 * 60 * 1e3;
3809
+ function assertDecryptTimeoutMs(timeoutMs, operationLabel) {
3810
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
3811
+ throw new CofheError({
3812
+ code: "INTERNAL_ERROR" /* InternalError */,
3813
+ message: `${operationLabel}: setTimeout(timeoutMs) expects a finite number greater than 0.`,
3814
+ context: { timeoutMs }
3815
+ });
3816
+ }
3817
+ }
3808
3818
  function normalize404RetryTimeoutMs(params) {
3809
3819
  const { timeoutMs, operationLabel, errorCode } = params;
3810
3820
  if (timeoutMs === void 0)
@@ -3943,7 +3953,6 @@ function parseDecryptedBytesToBigInt(decrypted) {
3943
3953
  // core/decrypt/tnSealOutputV2.ts
3944
3954
  var POLL_INTERVAL_MS = 1e3;
3945
3955
  var POLL_MAX_INTERVAL_MS = 1e4;
3946
- var SEAL_OUTPUT_TIMEOUT_MS = 5 * 60 * 1e3;
3947
3956
  var SUBMIT_RETRY_INTERVAL_MS = 1e3;
3948
3957
  function numberArrayToUint8Array(arr) {
3949
3958
  return new Uint8Array(arr);
@@ -4001,7 +4010,7 @@ function parseCompletedSealOutputResponse(params) {
4001
4010
  }
4002
4011
  return convertSealedData(sealed);
4003
4012
  }
4004
- async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, onPoll) {
4013
+ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, timeoutMs, onPoll) {
4005
4014
  const body = {
4006
4015
  ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
4007
4016
  host_chain_id: chainId,
@@ -4104,7 +4113,7 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp
4104
4113
  status: responseClassification.status,
4105
4114
  elapsedMs,
4106
4115
  retry404TimeoutMs,
4107
- overallTimeoutMs: SEAL_OUTPUT_TIMEOUT_MS,
4116
+ overallTimeoutMs: timeoutMs,
4108
4117
  thresholdNetworkUrl,
4109
4118
  body,
4110
4119
  attemptIndex,
@@ -4116,13 +4125,13 @@ async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, acp
4116
4125
  attemptIndex,
4117
4126
  elapsedMs,
4118
4127
  intervalMs: SUBMIT_RETRY_INTERVAL_MS,
4119
- timeoutMs: SEAL_OUTPUT_TIMEOUT_MS
4128
+ timeoutMs
4120
4129
  });
4121
4130
  await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS));
4122
4131
  attemptIndex += 1;
4123
4132
  }
4124
4133
  }
4125
- async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStartTime, onPoll) {
4134
+ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStartTime, timeoutMs, onPoll) {
4126
4135
  let attemptIndex = 0;
4127
4136
  while (true) {
4128
4137
  const elapsedMs = Date.now() - overallStartTime;
@@ -4136,17 +4145,17 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
4136
4145
  attemptIndex,
4137
4146
  elapsedMs,
4138
4147
  intervalMs,
4139
- timeoutMs: SEAL_OUTPUT_TIMEOUT_MS
4148
+ timeoutMs
4140
4149
  });
4141
- if (elapsedMs > SEAL_OUTPUT_TIMEOUT_MS) {
4150
+ if (elapsedMs > timeoutMs) {
4142
4151
  throw new CofheError({
4143
4152
  code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
4144
- message: `sealOutput polling timed out after ${SEAL_OUTPUT_TIMEOUT_MS}ms`,
4153
+ message: `sealOutput polling timed out after ${timeoutMs}ms`,
4145
4154
  hint: "The request may still be processing. Try again later.",
4146
4155
  context: {
4147
4156
  thresholdNetworkUrl,
4148
4157
  requestId,
4149
- timeoutMs: SEAL_OUTPUT_TIMEOUT_MS
4158
+ timeoutMs
4150
4159
  }
4151
4160
  });
4152
4161
  }
@@ -4234,6 +4243,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl, requestId, overallStart
4234
4243
  }
4235
4244
  async function tnSealOutputV2(params) {
4236
4245
  const { thresholdNetworkUrl, ctHash, chainId, acp, retry404TimeoutMs, onPoll } = params;
4246
+ const timeoutMs = params.timeoutMs ?? DEFAULT_DECRYPT_TIMEOUT_MS;
4237
4247
  const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
4238
4248
  timeoutMs: retry404TimeoutMs,
4239
4249
  operationLabel: "sealOutput",
@@ -4247,12 +4257,13 @@ async function tnSealOutputV2(params) {
4247
4257
  acp,
4248
4258
  overallStartTime,
4249
4259
  normalized404RetryTimeoutMs,
4260
+ timeoutMs,
4250
4261
  onPoll
4251
4262
  );
4252
4263
  if (submitResult.kind === "completed") {
4253
4264
  return submitResult.sealed;
4254
4265
  }
4255
- return await pollSealOutputStatus(thresholdNetworkUrl, submitResult.requestId, overallStartTime, onPoll);
4266
+ return await pollSealOutputStatus(thresholdNetworkUrl, submitResult.requestId, overallStartTime, timeoutMs, onPoll);
4256
4267
  }
4257
4268
 
4258
4269
  // core/decrypt/decryptForViewBuilder.ts
@@ -4264,6 +4275,7 @@ var DecryptForViewBuilder = class extends BaseBuilder {
4264
4275
  acp;
4265
4276
  pollCallback;
4266
4277
  retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS2;
4278
+ timeoutMs;
4267
4279
  constructor(params) {
4268
4280
  super({
4269
4281
  config: params.config,
@@ -4337,6 +4349,16 @@ var DecryptForViewBuilder = class extends BaseBuilder {
4337
4349
  this.retry404TimeoutMs = timeoutMs;
4338
4350
  return this;
4339
4351
  }
4352
+ /**
4353
+ * The whole budget of this decrypt in milliseconds, submit retries and status polling together
4354
+ * (5 minutes by default). Past it, `execute()` rejects with `SealOutputFailed`; a request still
4355
+ * processing on the threshold network is not cancelled.
4356
+ */
4357
+ setTimeout(timeoutMs) {
4358
+ assertDecryptTimeoutMs(timeoutMs, "decryptForView");
4359
+ this.timeoutMs = timeoutMs;
4360
+ return this;
4361
+ }
4340
4362
  withACP(acpOrACPHash) {
4341
4363
  if (typeof acpOrACPHash === "string") {
4342
4364
  this.acpHash = acpOrACPHash;
@@ -4466,6 +4488,7 @@ var DecryptForViewBuilder = class extends BaseBuilder {
4466
4488
  acp: wireAcp,
4467
4489
  thresholdNetworkUrl,
4468
4490
  retry404TimeoutMs: this.retry404TimeoutMs,
4491
+ timeoutMs: this.timeoutMs,
4469
4492
  onPoll: this.pollCallback
4470
4493
  });
4471
4494
  return ACPUtils.unseal(acp, sealed);
@@ -4568,7 +4591,6 @@ async function cofheMocksDecryptForTx(ctHash, utype, acp, publicClient) {
4568
4591
  // core/decrypt/tnDecryptV2.ts
4569
4592
  var POLL_INTERVAL_MS2 = 1e3;
4570
4593
  var POLL_MAX_INTERVAL_MS2 = 1e4;
4571
- var DECRYPT_TIMEOUT_MS = 5 * 60 * 1e3;
4572
4594
  var SUBMIT_RETRY_INTERVAL_MS2 = 1e3;
4573
4595
  function assertDecryptSubmitResponseV2(value) {
4574
4596
  if (value == null || typeof value !== "object") {
@@ -4685,7 +4707,7 @@ function assertDecryptStatusResponseV2(value) {
4685
4707
  }
4686
4708
  return value;
4687
4709
  }
4688
- async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, onPoll) {
4710
+ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp, overallStartTime, retry404TimeoutMs, timeoutMs, onPoll) {
4689
4711
  const body = {
4690
4712
  ct_tempkey: BigInt(ctHash).toString(16).padStart(64, "0"),
4691
4713
  host_chain_id: chainId
@@ -4792,7 +4814,7 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp,
4792
4814
  status: responseClassification.status,
4793
4815
  elapsedMs,
4794
4816
  retry404TimeoutMs,
4795
- overallTimeoutMs: DECRYPT_TIMEOUT_MS,
4817
+ overallTimeoutMs: timeoutMs,
4796
4818
  thresholdNetworkUrl,
4797
4819
  body,
4798
4820
  attemptIndex,
@@ -4804,13 +4826,13 @@ async function submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, acp,
4804
4826
  attemptIndex,
4805
4827
  elapsedMs,
4806
4828
  intervalMs: SUBMIT_RETRY_INTERVAL_MS2,
4807
- timeoutMs: DECRYPT_TIMEOUT_MS
4829
+ timeoutMs
4808
4830
  });
4809
4831
  await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS2));
4810
4832
  attemptIndex += 1;
4811
4833
  }
4812
4834
  }
4813
- async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartTime, onPoll) {
4835
+ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartTime, timeoutMs, onPoll) {
4814
4836
  let attemptIndex = 0;
4815
4837
  while (true) {
4816
4838
  const elapsedMs = Date.now() - overallStartTime;
@@ -4824,17 +4846,17 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
4824
4846
  attemptIndex,
4825
4847
  elapsedMs,
4826
4848
  intervalMs,
4827
- timeoutMs: DECRYPT_TIMEOUT_MS
4849
+ timeoutMs
4828
4850
  });
4829
- if (elapsedMs > DECRYPT_TIMEOUT_MS) {
4851
+ if (elapsedMs > timeoutMs) {
4830
4852
  throw new CofheError({
4831
4853
  code: "DECRYPT_FAILED" /* DecryptFailed */,
4832
- message: `decrypt polling timed out after ${DECRYPT_TIMEOUT_MS}ms`,
4854
+ message: `decrypt polling timed out after ${timeoutMs}ms`,
4833
4855
  hint: "The request may still be processing. Try again later.",
4834
4856
  context: {
4835
4857
  thresholdNetworkUrl,
4836
4858
  requestId,
4837
- timeoutMs: DECRYPT_TIMEOUT_MS
4859
+ timeoutMs
4838
4860
  }
4839
4861
  });
4840
4862
  }
@@ -4923,6 +4945,7 @@ async function pollDecryptStatusV2(thresholdNetworkUrl, requestId, overallStartT
4923
4945
  }
4924
4946
  async function tnDecryptV2(params) {
4925
4947
  const { thresholdNetworkUrl, ctHash, chainId, acp, retry404TimeoutMs, onPoll } = params;
4948
+ const timeoutMs = params.timeoutMs ?? DEFAULT_DECRYPT_TIMEOUT_MS;
4926
4949
  const normalized404RetryTimeoutMs = normalize404RetryTimeoutMs({
4927
4950
  timeoutMs: retry404TimeoutMs,
4928
4951
  operationLabel: "decrypt",
@@ -4936,12 +4959,13 @@ async function tnDecryptV2(params) {
4936
4959
  acp,
4937
4960
  overallStartTime,
4938
4961
  normalized404RetryTimeoutMs,
4962
+ timeoutMs,
4939
4963
  onPoll
4940
4964
  );
4941
4965
  if (submitResult.kind === "completed") {
4942
4966
  return submitResult;
4943
4967
  }
4944
- return await pollDecryptStatusV2(thresholdNetworkUrl, submitResult.requestId, overallStartTime, onPoll);
4968
+ return await pollDecryptStatusV2(thresholdNetworkUrl, submitResult.requestId, overallStartTime, timeoutMs, onPoll);
4945
4969
  }
4946
4970
 
4947
4971
  // core/decrypt/decryptForTxBuilder.ts
@@ -4953,6 +4977,7 @@ var DecryptForTxBuilder = class extends BaseBuilder {
4953
4977
  acpSelection = "unset";
4954
4978
  pollCallback;
4955
4979
  retry404TimeoutMs = DEFAULT_404_RETRY_TIMEOUT_MS3;
4980
+ timeoutMs;
4956
4981
  constructor(params) {
4957
4982
  super({
4958
4983
  config: params.config,
@@ -4995,6 +5020,11 @@ var DecryptForTxBuilder = class extends BaseBuilder {
4995
5020
  this.retry404TimeoutMs = timeoutMs;
4996
5021
  return this;
4997
5022
  }
5023
+ setTimeout(timeoutMs) {
5024
+ assertDecryptTimeoutMs(timeoutMs, "decryptForTx");
5025
+ this.timeoutMs = timeoutMs;
5026
+ return this;
5027
+ }
4998
5028
  withACP(acpOrACPHash) {
4999
5029
  if (this.acpSelection === "with-acp") {
5000
5030
  throw new CofheError({
@@ -5128,6 +5158,7 @@ var DecryptForTxBuilder = class extends BaseBuilder {
5128
5158
  acp: wireAcp,
5129
5159
  thresholdNetworkUrl,
5130
5160
  retry404TimeoutMs: this.retry404TimeoutMs,
5161
+ timeoutMs: this.timeoutMs,
5131
5162
  onPoll: this.pollCallback
5132
5163
  });
5133
5164
  return {
@@ -5248,6 +5279,12 @@ function createCofheClientBase(opts) {
5248
5279
  });
5249
5280
  }
5250
5281
  };
5282
+ const _requireIssuer = (acp, what) => {
5283
+ const sender = connectStore.getState().walletClient?.account?.address;
5284
+ if (sender == null || sender.toLowerCase() !== acp.issuer.toLowerCase()) {
5285
+ throw new Error(`Only the acp issuer can ${what}`);
5286
+ }
5287
+ };
5251
5288
  async function connect(publicClient, walletClient) {
5252
5289
  const state = connectStore.getState();
5253
5290
  if (state.connected && state.publicClient === publicClient && state.walletClient === walletClient)
@@ -5415,6 +5452,11 @@ function createCofheClientBase(opts) {
5415
5452
  const { walletClient } = connectStore.getState();
5416
5453
  return acps.revokeACP(acp, walletClient);
5417
5454
  },
5455
+ prepareRevokeACP: (acp) => {
5456
+ _requireConnected();
5457
+ _requireIssuer(acp, "revoke it");
5458
+ return acps.prepareRevokeACP(acp);
5459
+ },
5418
5460
  revokeAllACPs: async (revokerContract) => {
5419
5461
  _requireConnected();
5420
5462
  const { publicClient, walletClient } = connectStore.getState();
@@ -5438,6 +5480,21 @@ function createCofheClientBase(opts) {
5438
5480
  const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
5439
5481
  return acps.shareOnChain(acp, walletClient, sharingRegistry, { ...withAppKey(), ...options });
5440
5482
  },
5483
+ prepareShareOnChain: async (acp, options) => {
5484
+ _requireConnected();
5485
+ _requireIssuer(acp, "share it on-chain");
5486
+ const { publicClient } = connectStore.getState();
5487
+ const chainId = await publicClient.getChainId();
5488
+ const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
5489
+ return acps.prepareShareOnChain(acp, sharingRegistry, { ...withAppKey(), ...options });
5490
+ },
5491
+ prepareRemoveShare: async (shareId) => {
5492
+ _requireConnected();
5493
+ const { publicClient } = connectStore.getState();
5494
+ const chainId = await publicClient.getChainId();
5495
+ const sharingRegistry = await _resolveSharingRegistry(publicClient, chainId);
5496
+ return acps.prepareRemoveShare(shareId, sharingRegistry);
5497
+ },
5441
5498
  getIncomingShares: async () => {
5442
5499
  _requireConnected();
5443
5500
  const { publicClient, walletClient } = connectStore.getState();
package/dist/web.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- import { I as IStorage, C as CofheInputConfig, a as CofheConfig, b as CofheClient, E as EncryptableItem } from './clientTypes-C2b_qub5.cjs';
1
+ import { I as IStorage, C as CofheInputConfig, a as CofheConfig, b as CofheClient, E as EncryptableItem } from './clientTypes-D2djRDoH.cjs';
2
2
  import 'viem';
3
3
  import './types-C07FK-cL.cjs';
4
4
  import 'zod';
5
- import './onchain-utils-CgOslubH.cjs';
5
+ import './onchain-utils-Ns56cBm0.cjs';
6
6
  import 'zustand/vanilla';
7
7
 
8
8
  declare function createSsrStorage(): IStorage;
package/dist/web.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { I as IStorage, C as CofheInputConfig, a as CofheConfig, b as CofheClient, E as EncryptableItem } from './clientTypes-DEKYh0cw.js';
1
+ import { I as IStorage, C as CofheInputConfig, a as CofheConfig, b as CofheClient, E as EncryptableItem } from './clientTypes-B-qOZCx0.js';
2
2
  import 'viem';
3
3
  import './types-C07FK-cL.js';
4
4
  import 'zod';
5
- import './onchain-utils-CgOslubH.js';
5
+ import './onchain-utils-Ns56cBm0.js';
6
6
  import 'zustand/vanilla';
7
7
 
8
8
  declare function createSsrStorage(): IStorage;
package/dist/web.js CHANGED
@@ -1,9 +1,9 @@
1
- import { createCofheConfigBase, createCofheClientBase } from './chunk-GKEJHZ52.js';
1
+ import { createCofheConfigBase, createCofheClientBase } from './chunk-VE7DKXSF.js';
2
2
  import './chunk-UKQAJK4N.js';
3
- import './chunk-WAA2U7CT.js';
3
+ import './chunk-3L2IVPMI.js';
4
4
  import { initTfheThreadPool } from './chunk-KSOV5B4B.js';
5
- import { fheTypeToString, fromHexString } from './chunk-3SD2UCRE.js';
6
- import { TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT } from './chunk-OC5TGQGG.js';
5
+ import { fheTypeToString, fromHexString } from './chunk-WJGTPW7K.js';
6
+ import { TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT } from './chunk-J23FYAI2.js';
7
7
  import { constructClient } from 'iframe-shared-storage';
8
8
 
9
9
  // web/const.ts
@@ -1,6 +1,6 @@
1
1
  import { initTfheThreadPool } from './chunk-KSOV5B4B.js';
2
- import { fromHexString } from './chunk-3SD2UCRE.js';
3
- import { TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT } from './chunk-OC5TGQGG.js';
2
+ import { fromHexString } from './chunk-WJGTPW7K.js';
3
+ import { TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT } from './chunk-J23FYAI2.js';
4
4
 
5
5
  // web/zkProve.worker.ts
6
6
  var tfheModule = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cofhe/sdk",
3
- "version": "1.0.1",
3
+ "version": "1.1.0-alpha.1",
4
4
  "type": "module",
5
5
  "description": "SDK for Fhenix COFHE coprocessor interaction",
6
6
  "main": "./dist/core.cjs",
@@ -1,27 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { constructZkPoKMetadata } from '../encrypt/zkPackProveVerify.js';
3
- import { toHexString } from '../utils.js';
4
-
5
- describe('constructZkPoKMetadata', () => {
6
- const account = '0x1234567890123456789012345678901234567890';
7
- const contract = '0xbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef';
8
-
9
- it('lays out security zone, account, chain id and the consuming contract', () => {
10
- const metadata = constructZkPoKMetadata(account, 3, 0x010203, contract);
11
-
12
- expect(metadata.length).toBe(1 + 20 + 32 + 20);
13
- expect(metadata[0]).toBe(3);
14
- expect('0x' + toHexString(metadata.slice(1, 21))).toBe(account);
15
- const chainId = metadata.slice(21, 53);
16
- expect(Array.from(chainId.slice(0, 29))).toEqual(new Array(29).fill(0));
17
- expect(Array.from(chainId.slice(29))).toEqual([1, 2, 3]);
18
- expect('0x' + toHexString(metadata.slice(53))).toBe(contract);
19
- });
20
-
21
- it('accepts the consuming contract with or without the 0x prefix', () => {
22
- const withPrefix = constructZkPoKMetadata(account, 0, 1, contract);
23
- const withoutPrefix = constructZkPoKMetadata(account, 0, 1, contract.slice(2));
24
-
25
- expect(Array.from(withoutPrefix)).toEqual(Array.from(withPrefix));
26
- });
27
- });